spring boot原理初识

主程序

@SpringBootApplication

//SpringBootApplication 标注这个类是一个spring boot的应用
@SpringBootApplication
public class HelloApplication {
    //将spring boot启动
    public static void main(String[] args) {
        SpringApplication.run(HelloApplication.class, args);
    }
}

@SpringBootConfiguration

标注在某个类上 , 表示这是一个SpringBoot的配置类

@Configuration

说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件

@Component

说明启动类本身也是Spring中的一个组件

@EnableAutoConfiguration

自动配置

@AutoConfigurationPackage

自动配置包

@Import({AutoConfigurationImportSelector.class})

给容器导入组件
1.在AutoConfigurationImportSelector类中有这样一个方法

    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

2.在这个类中调用了SpringFactoriesLoader类的loadFactoryNames方法, 进入这个方法

    public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
        ClassLoader classLoaderToUse = classLoader;
        if (classLoader == null) {
            classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
        }

        String factoryTypeName = factoryType.getName();
        return (List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
    }

3.查看 loadSpringFactories 方法

    private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
        Map<String, List<String>> result = (Map)cache.get(classLoader);
        if (result != null) {
            return result;
        } else {
            HashMap result = new HashMap();

            try {
                Enumeration urls = classLoader.getResources("META-INF/spring.factories");

                while(urls.hasMoreElements()) {
                    URL url = (URL)urls.nextElement();
                    UrlResource resource = new UrlResource(url);
                    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                    Iterator var6 = properties.entrySet().iterator();

                    while(var6.hasNext()) {
                        Entry<?, ?> entry = (Entry)var6.next();
                        String factoryTypeName = ((String)entry.getKey()).trim();
                        String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                        String[] var10 = factoryImplementationNames;
                        int var11 = factoryImplementationNames.length;

                        for(int var12 = 0; var12 < var11; ++var12) {
                            String factoryImplementationName = var10[var12];
                            ((List)result.computeIfAbsent(factoryTypeName, (key) -> {
                                return new ArrayList();
                            })).add(factoryImplementationName.trim());
                        }
                    }
                }

                result.replaceAll((factoryType, implementations) -> {
                    return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
                });
                cache.put(classLoader, result);
                return result;
            } catch (IOException var14) {
                throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14);
            }
        }
    }

4.查看出现的资源文件META-INF/spring.factories
在这里插入图片描述

可以看出这些都是配置类,
所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件 ,并将其中对应的 org.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了 @Configuration的JavaConfig形式的IOC容器配置类 , 然后将这些都汇总成为一个实例并加载到IOC容器中。

结论:

SpringBoot在启动时从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入容器 , 自动配置类就生效,帮我们进行自动配置工作;

@ComponentScan

自动扫描包

posted @ 2022-01-05 16:10  ︶ㄣ演戲ㄣ  阅读(3)  评论(0编辑  收藏  举报  来源