Spring Boot 手摸手系列-自动配置原理(二)

/ 2020-08-01 / 1182人浏览 / 0人评论

上篇文章 Spring Boot 手摸手系列-自动配置原理(一) 介绍了 @EnableAutoConfigurationAutoConfigurationImportSelector  ,同时我们提出了问题,现在来看下将类路径下 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容器中


总结一下这两篇文章的结论

  1. springboot 启动会加载很多的自动配置类。
  2. 当我们使用开发时,先看使用的场景springboot是否提供了自动配置类。
  3. 再看自动配置类中提供了哪些组件,如果已经提供,则可以直接使用。
  4. 给容器中自动添加组件时,会从 Properties 类中获取某些属性,我们可以直接通过配置文件直接指定这些属性的值。

XXAutoConfiguration 某类场景下的自动配置类,往容器中添加组件

xxxProperties 封装某类场景下的相关属性类,根据配置文件绑定属性,并添加到ioc容器中

全部评论