个人理解、仅供参考。
先从启动类加上说
@SpringBootApplication
public class springBootHelloWorld {
public static void main(String[] args) {
SpringApplication.run(springBootHelloWorld.class,args);
}
}
@SpringBootApplication:标注这个类是springboot的主配置类、没有这个注解springboot是跑不起来的
要说自动配bean、我们点开注解开
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {}
看这个注解 @EnableAutoConfiguration :开启自动配置功能
@EnableAutoConfiguration:的内容
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
现在看这个 @Import(AutoConfigurationImportSelector.class)
@Import:是spring的注解、是将配置类导入到另一个配置类中
AutoConfigurationImportSelector.class:从字面意思可以得出是一个-》自动配置导包的选择器
作用就是:导入哪些组件到容器中、并选择导入、他有一个选择的作用
打开AutoConfigurationImportSelector.class类的selectImports方法
具体的操作就在绿色框框柱的地方、这个地方做的事情就是获取要自动装配的全部类、然后在进行过滤、最后将其过滤后的数据、自动注入到sprigIOC容器中
说一下这些方法都做了什么 、我自己认为的。
// 获取了@EnableAutoConfiguration注解的属性和值
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//这个获取了所有候选自动装配的xxxxAutoConfiguration全类名
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
//List中的元素去重、排序
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
//将其集合清空
configurations.removeAll(exclusions);
//将其过滤所需要自动装配的全类名
configurations = getConfigurationClassFilter().filter(configurations);
fireAutoConfigurationImportEvents(configurations, exclusions);
//将其赋值给AutoConfigurationEntry类的属性
return new AutoConfigurationEntry(configurations, exclusions);
如何获取了所有候选自动装配的xxxxAutoConfiguration全类名???
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
就是这个方法来获取getCandidateConfigurations(annotationMetadata, attributes)
一开始调用了getCandidateConfigurations方法
进入方法后调用了SpringFactoriesLoader类的loadFactoryNames方法
进入这个方法后调用了loadSpringFactories() 方法
FACTORIES_RESOURCE_LOCATION = META-INF/spring.factories
loadSpringFactories() 方法
:作用就是读取META-INF/spring.factories(具体位置就是:org/springframework/boot/spring-boot/2.3.3.RELEASE/spring-boot-2.3.3.RELEASE.jar!/META-INF/spring.factories)位置的一个配置文件
通过debug可以看到准确的路径、通过这个路径我们去看一下META-INF/spring.factories东西
可以看到这些xxxAutoConfiguration配置类
最后得出结论这个方法就是获取全部xxxAutoConfiguration配置类
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
可以很清楚的看到将org/springframework/boot/spring-boot/2.3.3.RELEASE/spring-boot-2.3.3.RELEASE.jar!/META-INF/spring.factories
文件中xxxAutoConfiguration配置类的全类名读取到集合中 一共127个
继续接着往下走
从图中可以看出由之前的127个变成了23了、这就说明了在绿框中、做的事情就是将数据过滤的一遍、
最后将过滤后的全类名的自动配置类、通过这些全类名的自动配置类将其全部添加到spring容器中
小结:
org/springframework/boot/spring-boot/2.3.3.RELEASE/spring-boot-2.3.3.RELEASE.jar!/META-INF/spring.factories
文件中的全部xxxAutoConfiguration配置类、最后会将其全部配置类进行过滤筛选、选出本项目所依赖的自动配置类、然后将其配置类中的bean配置到springIOC容器中、