SpringBoot源码分析——【SpringBoot自动装配原理】

3、SpringBoot自动装配

个人理解、仅供参考。

3.1、@SpringBootApplication

先从启动类加上说

@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 {}

3.2、@EnableAutoConfiguration

看这个注解 @EnableAutoConfiguration :开启自动配置功能

@EnableAutoConfiguration:的内容

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}

3.3、@Import(AutoConfigurationImportSelector.class)

现在看这个 @Import(AutoConfigurationImportSelector.class)

@Import:是spring的注解、是将配置类导入到另一个配置类中

AutoConfigurationImportSelector.class:从字面意思可以得出是一个-》自动配置导包的选择器

作用就是:导入哪些组件到容器中、并选择导入、他有一个选择的作用

打开AutoConfigurationImportSelector.class类的selectImports方法

SpringBoot源码分析——【SpringBoot自动装配原理】_第1张图片

具体的操作就在绿色框框柱的地方、这个地方做的事情就是获取要自动装配的全部类、然后在进行过滤、最后将其过滤后的数据、自动注入到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)

SpringBoot源码分析——【SpringBoot自动装配原理】_第2张图片

一开始调用了getCandidateConfigurations方法进入方法后调用了SpringFactoriesLoader类的loadFactoryNames方法进入这个方法后调用了loadSpringFactories() 方法

SpringBoot源码分析——【SpringBoot自动装配原理】_第3张图片

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)位置的一个配置文件
SpringBoot源码分析——【SpringBoot自动装配原理】_第4张图片

通过debug可以看到准确的路径、通过这个路径我们去看一下META-INF/spring.factories东西

SpringBoot源码分析——【SpringBoot自动装配原理】_第5张图片

可以看到这些xxxAutoConfiguration配置类

最后得出结论这个方法就是获取全部xxxAutoConfiguration配置类

List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);

然后我们回到这个地方进行debug
SpringBoot源码分析——【SpringBoot自动装配原理】_第6张图片

可以很清楚的看到将org/springframework/boot/spring-boot/2.3.3.RELEASE/spring-boot-2.3.3.RELEASE.jar!/META-INF/spring.factories文件中xxxAutoConfiguration配置类的全类名读取到集合中 一共127个

继续接着往下走

SpringBoot源码分析——【SpringBoot自动装配原理】_第7张图片

从图中可以看出由之前的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容器中、
  • 当中的过滤筛选、个人理解就是通过pom文件中starter中的jar包来进行匹配过滤、将其所的自动配置类注册到spring容器当中

你可能感兴趣的:(spring,boot)