在springboot中我们第一眼看到的注解就是@SpringBootApplication,我们都知道这是一个复合注解。提醒一下想看源码的朋友千万不要看到方法就想点进去,那样的话spring会把你搞吐。废话不多说,开搞……
@SpringBootApplication注解
我们都知道想了解这个注解 一般会关注这三个注解:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan。@SpringBootConfiguration、@ComponentScan他们就不说了,我们今天的重点是@EnableAutoConfiguration。springboot的动装配在SpringBoot中是通过@EnableAutoConfiguration的注解来实现的。
我们来跟踪源码,再次建议在看源码的时候千万不要看到什么都要点进去看一下。查看@EnableAutoConfiguration注解我们会看到它还是复合注解
大家如果经常阅读源码的话会看见@import和@Conditional这两个注解,@import这个注解的作用就是导入类。
@Import({AutoConfigurationImportSelector.class})
AutoConfigurationImportSelector这个类最终实现了ImportSelector,ImportSelector是一个接口,里面有一个抽象方法,返回的是一个String数组,在这个数组中可以指定需要装配到IOC容器的类,当在@Import中导入它的实现类侯,就会把该类中返回的Class名称都装载到IOC容器中
根据源码分析,大家可以想到springboot自动装配的核心是扫描约定目录下的文件进行解析(约定大于配置),解析后将得到的Configuration配置类通过ImportSelector进行导入(一个或者多个),完成Bean的自动装配。那么我们下面仔细分析下AutoConfigurationImportSelector中的selectImport方法
AutoConfigurationImportSelector主要有两个功能:
1.从META-INF/spring.factories中加载自动装配的条件元数据,简单来说就是只有满足条件的Bean才能够进行装配
2.收集所有符合条件的配置类 antoConfigurationEntry.getConfiguration(),完成装配。
关于META-INF/spring.factories其实我们会在POM文件中的starter中会看到META-INF/spring.factories。selectImports的核心就是去扫描这个文件,把里面的类自动加载到spring的容器中。
核心加载过程、核心加载过程、核心加载过程
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
//获得@EnableAutoConfiguration注解中的属性exclude excludeName等
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
List<String> configurations =
//获得所有自动装配的配置类
this.getCandidateConfigurations(annotationMetadata, attributes);
//去除重复的配置项
configurations = this.removeDuplicates(configurations);
//根据@EnableAutoConfiguration注解中配置的exclude等属性,把不需要的自动装配的类去除
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.filter(configurations, autoConfigurationMetadata);
//广播事件
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
如以redis为例,它的装配流程:
总结:springboot自动装配的思想就是它获取所有的配置类,通过去重、exclude排除等操作,得到最终需要实现自动装配的配置类。这里需要关注的就是getCandidateConfigurations 他是配置类 最核心 最核心 最核心的方法,重要的事情说三遍
自己的见解,大神勿喷,共同学习