自动配置原理
在SpringBoot小记(一)中已经简述了SpingBoot的自动配置原理,今天再对它的过程做进一步的说明。
在上篇文章中讲到SpringBoot启动的时候加载主配置类,通过@EnableAutoConfiguration注解开始了自动配置的功能然后导入了META-INF/spring.factories中EnableAutoConfiguration对应的全类名,将他们加载到容器中。
他们每一个自动配置类都能够进行相应的自动配置功能。
这里我们随便打开一个自动配置类,比如:HttpEncodingAutoConfiguration
打开这个类中,我们就能看到这个类上面标记了好多的注解
@Configuration @EnableConfigurationProperties(HttpProperties.class) @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) @ConditionalOnClass(CharacterEncodingFilter.class) @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) public class HttpEncodingAutoConfiguration { private final HttpProperties.Encoding properties; public HttpEncodingAutoConfiguration(HttpProperties properties) { this.properties = properties.getEncoding(); } @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
这个表示该类是一个配置类,相当于我们之前编写的配置文件一样,同时还会给容器添加组件 - @EnableConfigurationProperties(HttpProperties.class)
启用指定类的ConfigurationProperties功能。能将配置文件中的值和对应的xxxxProperties绑定起来,并把HttpProperties添加到容器中。
当我们进入HttpProperties类中的时候我们会发现,他的上边有一个@ConfigurationProperties(prefix = "spring.http"),@ConfigurationProperties表明从配置文件中获取指定的值和bean的属性进行绑定,这个给我们做了提醒,当我们在application.yml文件中编写配置信息的时候,就参考改配置类的获取形式写即可,这个类的下面还有很多属性,也代表着我们在编写配置文件的时候也可以有选择性的去重新编写这些值。 - @ConditionalXXXXX
@ConditionalXXXX的注解底层都是基于Spring的@Conditional注解进行扩展的,根据不同的条件,如果满足条件整个配置类的配置才会起作用。
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
这几个注解全部都是被扩展的,进行判断,来确定该配置类是否会生效
下面还有一个@Bean是将方法的返回值添加到Spring容器中去,在这里可以看到我们用到了properties中的属性,而这个properties就来源于我们之前开启注解进行配置生成的HttpProperties对象。@ConditionalOnMissingBean也是扩展的新注解,当我们容器中没有相应的类的时候就会执行下面的方法。@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; }
同时我们可以看到这个HttpEncodingAutoConfiguration只有一个有参构造器,在这种情况下,构造器中的值默认是去Spring容器中获取public HttpEncodingAutoConfiguration(HttpProperties properties) { this.properties = properties.getEncoding(); }
总结
- xxxxxAutoConfiguration:自动配置类,给容器中添加组件
- xxxxxProperties:封装配置文件中的相关属性
- @Conditionalxxxx系列
- 自动配置类有些也不一定启用,必须满足相应的条件