SpringBoot自动配置原理
自动包规则原理
SpringBoot应用的启动类:
1 2 3 4 5 6
| @SpringBootApplication public class MainApplication { public static void main(String[] args) { SpringApplication.run(MainApplication.class, args); } }
|
@SpringBootApplication
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @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
1 2 3 4 5 6 7 8 9 10 11 12 13
| @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 {}; }
|
@AutoConfigurationPackage
标签名直译为:自动配置包,指定了默认的包规则。
1 2 3 4 5 6 7 8 9 10
| @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import(AutoConfigurationPackages.Registrar.class) public @interface AutoConfigurationPackage { String[] basePackages() default {};
Class<?>[] basePackageClasses() default {}; }
|
- 利用Registrar给容器中导入一系列组件
- 将指定的一个包下的所有组件导入进来,也就是MainApplication所在包下。
@Import(AutoConfigurationImportSelector.class)
- 利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
- 调用
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)
获取到所有需要导入到容器中的配置类
- 利用工厂加载
Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);
得到所有的组件
- 从
META-INF/spring.factories
位置来加载一个文件。
- 默认扫描我们当前系统里面所有
META-INF/spring.factories
位置的文件
spring-boot-autoconfigure-2.3.4.RELEASE.jar
包里面也有META-INF/spring.factories
1 2 3 4 5 6 7
| # 文件里面写死了spring-boot一启动就要给容器中加载的所有配置类 # spring-boot-autoconfigure-2.3.4.RELEASE.jar/META-INF/spring.factories # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ ...
|
虽然我们127个场景的所有自动配置启动的时候默认全部加载,但是xxxxAutoConfiguration
按照条件装配规则(@Conditional
),最终会按需配置。
如AopAutoConfiguration
类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Configuration( proxyBeanMethods = false ) @ConditionalOnProperty( prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true ) public class AopAutoConfiguration { public AopAutoConfiguration() { } ... }
|
自动配置流程
总结:
- SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
- 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。(xxxxProperties里面读取,xxxProperties和配置文件进行了绑定)
- 生效的配置类就会给容器中装配很多组件
- 只要容器中有这些组件,相当于这些功能就有了
- 定制化配置
- 用户直接自己@Bean替换底层的组件
- 用户去看这个组件是获取的配置文件什么值就去修改。
xxxxxAutoConfiguration —> 组件 —> xxxxProperties里面拿值 —-> application.properties