目录
自动配置原理理解
SpringBoot 自动加载所有配置,按照需要加载,如果手动配置了,就以用户配置的为主。每一个配置类都会绑定配置一个 xxxProperties 类,每个 xxxProperties 类对应一个 xxxProperties 配置文件。
引导加载自动配置类
@SpringBootApplication
SpringBoot 应用主程序类上的注解 @SpringBootApplication
,表明了程序的入口,这个注解由三个注解组合而成
- @SpringBootConfiguration
就是一个 @Configuration - @ComponentScan
指定扫描包 - @EnableAutoConfiguration
自动配置注解
@EnableAutoConfiguration
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
@AutoConfigurationPackage
自动配置包注解
// 利用 Registrar 向容器中导入一系列组件
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
}
Registar
类
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
Registrar() {
}
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
// 获取到主程序类所在的包,将这个包下的所有组件批量注册到容器中
// 所以SpringBoot应用默认所有的组件都在 主程序类所在的包下
AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
}
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new AutoConfigurationPackages.PackageImports(metadata));
}
}
AutoConfigurationImportSelector
// 获取自动配置集合
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
// 获取所有需要导入容器的组件
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
configurations = this.removeDuplicates(configurations);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.getConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
利用 Map<String, List> loadSpringFactories(@Nullable ClassLoader classLoader) 方法得到所有的组件,这个方法默认扫描系统里 所有的 META-INF/spring.factories 文件
这个文件在SpringBoot自动配置的核心 spring-boot-autoconfigure-2.3.12.RELEASE.jar 中也有
SpringBoot 启动,默认就会加载所有场景配置,可以按需自动配置
按需自动配置
得益于SpringBoot的按条件配置 @Conditional ,可以根据实际场景加载需要的配置,,并且,当没有手动配置的时候才自动配置
例如:
再例如:
再例如:
Http字符编码过滤器的自动配置
定制化配置
用户可以自己通过 @Bean 方式替换底层组件
也可以修改组件从配置文件获取的值
自动配置流程总结
导入所有的自动配置类 xxxAutoConfiguration
按需加载组件
组件从 xxxProperties 配置类中获取值
xxxProperties 配置类从 xxxProperties 配置文件获取值