Spring Boot自动配置原理

每一个Spring Boot项目都有一个全局配置文件,application.properties或者application.yml,我们可以通过在全局配置文件中配置所需的值,来改变Spring Boot的默认配置。要明白每个配置的作用,以及如何进行配置,可以通过官方文档来进行查看。除此之外,还可以掌握自动配置的原理,来进行需要的配置。
官方示例如下:常见配置说明
Spring Boot自动配置原理_第1张图片
Spring Boot在启动的时候会加载主配置类,即被@SpringBootApplication标记的类,并且使用@EnableAutoConfiguration开启了自动配置的功能。
@EnableAutoConfiguration的作用:

  • 利用@Import({AutoConfigurationImportSelector.class})给容器中添加组件。
  • 通过List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);获取配置信息。在这个方法中,主要是通过SpringFactoriesLoader.loadFactoryNames扫描类路径下META-INF/spring.factories的文件内容,然后把扫描到的内容封装成properties对象,再从properties中获取EnableAutoConfiguration.class类(类名)对应的值,最后把他们添加到容器中。

其中,spring.factories文件是一组组key=value的形式。key是EnableAutoConfiguration类的全类名,value是xxxAutoConfiguration的类名列表,这些类名之间以逗号分隔。如图所示:
Spring Boot自动配置原理_第2张图片自动配置生效:
每一个xxxAutoConfiguration自动配置类都是在满足一定条件下才会生效,这些条件限制,在Spring Boot中以注解的形式体现,常见的条件注解如下:

  • @ConditionalOnBean:当容器里有指定的Bean的条件下。
  • @ConditionalOnMissingBean:当容器里不存在指定Bean的条件下。
  • @ConditionalOnClass:当类路径下有指定类的条件下。
  • @ConditionalOnMissingClass:当类路径下不存在指定类的条件下。
  • @ConditionalOnWebApplication:当前应用是web应用
  • @ConditionalOnNotWebApplication:当前应用不是web应用
  • @ConditionalOnProperty(prefix = “spring.http.encoding”,value = {“enabled”},matchIfMissing =
    true)当前配置文件中是否存在这个配置spring.http.encoding.enabled,如果不存在,判断也成了,即配置文件中不配置这一项,也是默认生效的。

以HttpEncodingAutoConfiguration为例解释自动配置原理

@Configuration // 这是一个配置类,类似于之前的配置文件,可以给容器中添加组件
@EnableConfigurationProperties({HttpProperties.class}) // 启动指定类(HttpProperties.class)的ConfigurationProperties功能,将配置文件中对应的值和HttpProperties绑定起来,并把HttpProperties加入到容器中。
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class}) // 判断当前项目中是否有CharacterEncodingFilter这个类,它主要是解决乱码的过滤器
@ConditionalOnProperty(
    prefix = "spring.http.encoding",
    value = {"enabled"},
    matchIfMissing = true
)// 判断当前配置文件是否有spring.http.encoding.enabled这个配置,如果不存在,默认生效
public class HttpEncodingAutoConfiguration {
    private final Encoding properties;

    public HttpEncodingAutoConfiguration(HttpProperties properties) {
        this.properties = properties.getEncoding();
    }

    @Bean // 给容器中添加组件,这个组件部分值需要从properties文件中获取
    @ConditionalOnMissingBean
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
        filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
        return filter;
    }

通过@EnableConfigurationProperties注解开启HttpProperties类的ConfigurationProperties功能。在HttpProperties类中,@ConfigurationProperties注解的作用就是将配置文件中以spring.http为前缀的配置,绑定到对应的Bean中。而@EnableConfigurationProperties负责将HttpProperties注入到容器中。由此可看,所有配置文件能配置的属性都是在xxxProperties类中封装着,配置文件中能配置哪些属性,就可以查看其对应的xxxProperties类。
根据源码可以看出,只有满足一定条件,这个配置类才可以生效,一旦这个配置类生效,就会向容器中添加各种组件。

  • xxxAutoConfiguration:自动配置类,目的是给容器中添加组件。

  • xxxProperties:属性配置类,全局配置文件(yml/properties)中能配置的值就来源于此。

总结:
在Spring Boot启动的时候,通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,这些配置类的格式都是xxxAutoConfiguration。目的是给容器中添加各种各样的组件,而各种组件所需的属性都封装在xxxProperties类中,而properties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性绑定的。

你可能感兴趣的:(spring,boot注解,spring,boot,自动配置原理)