Spring Boot 自动化配置原理
我们经常使用Spring Boot,是否知道Spring Boot自动化配置是怎么实现的呢?
一 初识自动化配置
Spring Boot自动化配置依赖于@EnableAutoConfiguration注解
该注解会在@SpringBootApplication中包含
该注解为一个复合注解包含了以下注解
@SpringBootConfiguration 标识该类是一个配置类
@EnableAutoConfiguration 开启自动化配置
@ComponentScan 扫描该类下的所有包配置的bean
二 揭开自动化配置面纱
@EnableAutoConfiguration 今天我们主要关注的是这个注解
此注解为一个复合注解包含了@AutoConfigurationPackage 该注解会导入一个AutoConfigurationPackages类
该方法将主程序类所在包及所有子包下的组件到扫描到spring容器中完成项目包下组件的自动注册
至此我们完成了自动化配置中自己的组件的自动化配置,那么我们依赖的jar包自动化配置说怎么实现的呢,请继续往下看
三 深入自动化配置
我们继续回到EnableAutoConfiguration注解
该注解包含2个属性:
exclude:根据类排除不使用的自动配置;
excludeName:根据类名排除不使用的自动配置;
并导入了AutoConfigurationImportSelector类 该类的核心方法为getCandidateConfigurations通过该方法即可获取到(spring-boot-2.1.3.RELEASE.jar/META-INF/spring.factories) 下的配置文件,该文件为spring boot自动化配置的配置文件,至此我们获取到的是所有的自动化配置类,那么spring boot的按需导入是怎么实现的呢,请继续往下看
因为spring boot是按需配置所以我们还需要根据引入的依赖筛选出需要的配置,核心方法如下
protected AutoConfigurationEntry getAutoConfigurationEntry(
AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
//判断是否开启自动配置
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//获取自动配置文件和配置
List configurations = getCandidateConfigurations(annotationMetadata,
attributes);//删除重复项
configurations = removeDuplicates(configurations);//获取排除的自动化配置
Set exclusions = getExclusions(annotationMetadata, attributes);//检查排除的自动化配置
checkExcludedClasses(configurations, exclusions);//移除排除的自动化配置
configurations.removeAll(exclusions);//根据引入的依赖按需导入自动配置
configurations = filter(configurations, autoConfigurationMetadata);//触发自动化配置
fireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationEntry(configurations, exclusions);
}
protected AutoConfigurationEntry getAutoConfigurationEntry(
AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
//判断是否开启自动配置
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//获取自动配置文件和配置
List configurations = getCandidateConfigurations(annotationMetadata,
attributes);//删除重复项
configurations = removeDuplicates(configurations);//获取排除的自动化配置
Set exclusions = getExclusions(annotationMetadata, attributes);//检查排除的自动化配置
checkExcludedClasses(configurations, exclusions);//移除排除的自动化配置
configurations.removeAll(exclusions);//根据引入的依赖按需导入自动配置
configurations = filter(configurations, autoConfigurationMetadata);//触发自动化配置
fireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationEntry(configurations, exclusions);
}
filter方法会过滤我们的自动化配置类 ,规则是根据我们配置类上的 @Conditiona系列注解