注:该源码分析对应SpringBoot版本为2.1.0.RELEASE
本篇接 助力SpringBoot自动配置的条件注解ConditionalOnXXX分析--SpringBoot源码(三)
温故而知新,我们来简单回顾一下上篇的内容,上一篇我们分析了SpringBoot的条件注解@ConditionalOnXxx的相关源码,现挑重点总结如下:
@ConditionalOnXxx
的条件类OnXxxCondition
都是继承于SpringBootCondition
基类,而SpringBootCondition
又实现了Condition
接口。SpringBootCondition
基类主要用来打印一些条件注解评估报告的日志,这些条件评估信息全部来源于其子类注解条件类OnXxxCondition
,因此其也抽象了一个模板方法getMatchOutcome
留给子类去实现来评估其条件注解是否符合条件。AutoConfigurationImportFilter
接口,这篇文章我们来填一下这个坑。前面我们分析了跟SpringBoot的自动配置息息相关内置条件注解@ConditionalOnXxx
后,现在我们就开始来撸SpringBoot自动配置的相关源码了。
在开始前,我们先想一下,SpringBoot为何一个标注有@SpringBootApplication
注解的启动类通过执行一个简单的run
方法就能实现SpringBoot大量Starter
的自动配置呢?
其实SpringBoot的自动配置就跟@SpringBootApplication
这个注解有关,我们先来看下其这个注解的源码:
@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 { // ...省略非关键代码 } 复制代码
@SpringBootApplication
标注了很多注解,我们可以看到其中跟SpringBoot自动配置有关的注解就有一个即@EnableAutoConfiguration
,因此,可以肯定的是SpringBoot的自动配置肯定跟@EnableAutoConfiguration
息息相关(其中@ComponentScan
注解的excludeFilters
属性也有一个类AutoConfigurationExcludeFilter
,这个类跟自动配置也有点关系,但不是我们关注的重点)。
现在我们来打开@EnableAutoConfiguration
注解的源码:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; } 复制代码
看到@EnableAutoConfiguration
注解又标有@AutoConfigurationPackage
和@Import(AutoConfigurationImportSelector.class)
两个注解,顾名思义,@AutoConfigurationPackage
注解肯定跟自动配置的包有关,而AutoConfigurationImportSelector
则是跟SpringBoot的自动配置选择导入有关(Spring中的ImportSelector
是用来导入配置类的,通常是基于某些条件注解@ConditionalOnXxxx
来决定是否导入某个配置类)。
因此,可以看出AutoConfigurationImportSelector
类是我们本篇的重点,因为SpringBoot的自动配置肯定有一个配置类,而这个配置类的导入则需要靠AutoConfigurationImportSelector
这个哥们来实现。
接下来我们重点来看AutoConfigurationImportSelector
这个类,完了我们再简单分析下@AutoConfigurationPackage
这个注解的逻辑。
可以肯定的是SpringBoot的自动配置的逻辑肯定与AutoConfigurationImportSelector这个类有关,那么我们该如何去找到SpringBoot自动配置实现逻辑的入口方法呢?
在找SpringBoot自动配置实现逻辑的入口方法前,我们先来看下AutoConfigurationImportSelector
的相关类图,好有个整体的理解。看下图:
可以看到AutoConfigurationImportSelector
重点是实现了DeferredImportSelector
接口和各种Aware
接口,然后DeferredImportSelector
接口又继承了ImportSelector
接口。
自然而然的,我们会去关注AutoConfigurationImportSelector
复写DeferredImportSelector
接口的实现方法selectImports
方法,因为selectImports
方法跟导入自动配置类有关,而这个方法往往是程序执行的入口方法。经过调试发现selectImports
方法很具有迷惑性,se