Spring Boot 学习(二)— 自动配置原理入门

自动配置原理的了解主要从了解@SpringBootApplication开始

第一步:从@SpringBootApplication开始

@SpringBootApplication的原理主要是下面三个注解:

  • @SpringBootConfiguration :
    该注解的核心:@Configuration,即代表当前是一个配置类;
    所以@SpringBootConfiguration的作用就是代表当前是一个配置类
  • @ComponentScan:
    作用:指定扫描的规则,如默认扫描主类所在的包即子包
  • @EnableAutoConfiguration :
    该注解的核心:
    @AutoConfigurationPackage
    @Import({AutoConfigurationImportSelector.class})
  • 在@AutoConfigurationPackage注解中使用了@Import({Registrar.class}),利用Registrar给容器中导入一系列组件,将指定包中的所有组件都导入到“主类(MainApplication)”所在的包中。
  • @Import({AutoConfigurationImportSelector.class}),中通过AutoConfigurationImportSelector类中的getAutoConfigurationEntry(annotationMetadata)给容器中批量导入一系列组件、通过getCandidateConfigurations(annotationMetadata,attributes)获取到所有需要导入到容器中的配置类;

默认扫描所有META-INF/spring.factories位置的文件,得到所有的组件。只要应用一启动就会加载所有的配置类。

注意:虽然会加载所有的配置类,但是会按照条件装配规则,即@Conditional,开启按需配置。

第二步:修改默认配置

  1. 如果我们不想使用springboot自动配置的某个组件,如何解决?
    我们可以在自己配置类中配置自己的组件来替代它,SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先
    如自动配置了文件上传解析器MultipartResolver,我们可以在自己得配置类中替换它,如下写:
@Bean
public MultipartResolver multipartResolver(MultipartResolver resolver){
    //写上自己得业务逻辑
    return resolver;
}
  1. 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值,保存在xxxxProperties里面,xxxProperties和配置文件进行了绑定。可以参考官网文档,如:
    server.port=8888

第三步:总结

@SpringBootApplication:

  • @SpringBootConfiguration:当前是一个配置类
  • @ComponentScan:指定扫描
  • @EnableAutoConfiguration :开启自动配置
  • @AutoConfigurationPackage:@Import({Registrar.class})导入Registrar,利用Registrar将指定包中的所有组件导入到,主类所在包中
  • @Import({AutoConfigurationImportSelector.class})利用AutoConfigurationImportSelector中的:
  • getAutoConfigurationEntry(annotationMetadata)为容器导入一系列组件
  • getCandidateConfigurations(annotationMetadata, attributes)获取所有需要导入到容器中的配置类

扫描所有META-INF/spring.factories位置的文件:得到所有的组件,应用启动自动加载全部

按需配置:按照条件装配规则,即@Conditional,开启按需配置,配置后便生效
装配组件:生效的配置类会为容器装配很多组件

简单来说:Springboot加载所有自动配置类(xxxxxAutoConfiguration),自动配置类按需生效(自动配置类默认会绑定配置文件的值,配置文件与xxxproperties文件绑定),生效的配置类为容器添加组件,所有应用就具有了这些组件的功能

定制化配置:
xxxxxAutoConfiguration —> 组件 —> xxxxProperties里面拿值 ----> application.properties