上篇文章 Spring Boot 手摸手系列-自动配置原理(一) 介绍了 @EnableAutoConfiguration 和 AutoConfigurationImportSelector ,同时我们提出了问题,现在来看下将类路径下 META-INF/spring.factories 中含有 EnableAutoConfiguration.class
的值加入到容器中 ,它具体的操作分析:
1、springboot 中 XXAutoConfiguration 类都是注入到容器中的组件,也是相应场景自动配置类
下面以HttpEncodingAutoConfiguration (HTTP 编码自动配置类)来说明一下自动配置原理, HttpEncodingAutoConfiguration 的源码如下:
@Configuration(proxyBeanMethods = false)
// 从配置文件中获取 spring.http 的属性与HttpProperties 这个bean 属性进行绑定,并将HttpProperties 注入到ioc容器中
@EnableConfigurationProperties(HttpProperties.class)
// @Conditionalxxx 底层都是基于 spring @Conditional 的注解,其实就是根据不同条件判断是否成立,且只有条件成立,配置类才会生效。
// 是来判断当前应用是否是web应用,如果是配置类生效。
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
// 判断当前项目有没有 CharacterEncodingFilter.class 这个类
@ConditionalOnClass(CharacterEncodingFilter.class)
// 判断配置文件中是否存在 spring.http.encoding. enabled ,如果不存在则为true,存在则根据这个值绑定。
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
// 取的值就是 HttpProperties 中的内部类 Encoding,从配置文件中读取的属性
private final HttpProperties.Encoding properties;
// 只有一个有参构造器时,参数值properties 就会从ioc容器中获取
public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
}
// 给容器中添加一个 CharacterEncodingFilter 的组件
// this.properties 通过构造器拿到
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
return filter;
}
@Configuration(proxyBeanMethods = false)
表示这是一个配置类,且是Lite模式;何为 Lite模式 ?参考这里文章
2、配置文件中的属性都对应着 xxxProperties 类中的属性
@EnableConfigurationProperties(HttpProperties.class)
这个注解是启用 ConfigurationProperties 功能,它指定启用的是 HttpProperties.class
@ConfigurationProperties(prefix = "spring.http")
public class HttpProperties {
查看 HttpProperties.class
源码发现,就是从配置文件中获取 spring.http 的属性与HttpProperties 这个bean 属性进行绑定,并将HttpProperties添加到ioc容器中
总结一下这两篇文章的结论
XXAutoConfiguration 某类场景下的自动配置类,往容器中添加组件
xxxProperties 封装某类场景下的相关属性类,根据配置文件绑定属性,并添加到ioc容器中
全部评论