springBoot2自动配置原理

自动配置原理

  1. SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration

  2. @EnableAutoConfiguration作用:

    利用AutoConfigurationImportSelector给容器导入了一些配置 AutoConfigurationImportSelector

    获取候选配置

    1
    List<String> configurations =  getCandidateConfigurations(annotationMetadata, attributes);

    通过getCandidateConfigurations(…)方法中调用的SpringFactoriesLoader.loadFactoryNames(…)扫描类路径下”META-INF/spring.factories”的所有资源。

    1
    SpringFactoriesLoader.FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

    默认配置路径

    将扫描到的文件内容包装成properties对象。

    再通过properties对象中获取EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中。

    最终会将类路径下的 META-INF/spring.factories中配置的所有EnableAutoConfiguration的值加入到容器中

    每一个xxxAutoConfiguration类都是容器中的组件,都加入到容器中,来进行自动配置。

  1. HttpEncodingAutoConfiguration为例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    // 注解的方式表示这是一个配置类,跟以前编写的配置文件一样。
    @Configuration
    /* 启动指定类的 ConfigurationProperties功能,此处为 HttpProperties.class
    * 将配置文件中对应的值和 HttpProperties绑定起来,详细如下 ^4.
    */
    @EnableConfigurationProperties(HttpProperties.class)
    /* Spring底层的 @Conditional注解(Spring注解版),根据不同的条件,
    * 如果满足注解所要求的条件,则整个配置类生效。
    * 此处是判断应用时候是web应用,如果是,当前配置类生效,并把HttpProperties加入到容器中
    */
    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
    /* 判断当前项目(系统)中有没有CharacterEncodingFilter.class这个类。
    * 作用是用于解决SpringMVC中解决乱码的过滤器。
    */
    @ConditionalOnClass(CharacterEncodingFilter.class)
    /* 判断配置文件中是否存在某个配置 spring.http.encoding.enable;
    * 如果不存在判断也是成立的。
    * 即使在我们自己的文件中不配置 spring.http.encoding.enable = true,
    * 在这里也默认配置生效了,原因->matchIfMissing = true
    */
    @ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled",
    matchIfMissing = true)
    public class HttpEncodingAutoConfiguration {

    // 它已经和springBoot的配置文件映射了
    private final HttpProperties.Encoding properties;

    // 只有一个有构造器的情况下,参数的值就会从容器中拿 ->@EnableConfigurationProperties
    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(Type.REQUEST));
    filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
    return filter;
    }

    ...

    }

    ​ 最终根据当前配置类注解的条件,来决定配置类是否生效。

    ​ 一旦这配置类生效;这个配置类就会给容器添加各种组件,

    ​ 这些组件的属性是从对应的properties中获取的,这些类的每一个属性都是和配置文件绑定的;

  1. 所有配置文件中能配置的属性都是在xxxProperties类中封装着,配置文件能配置什么就可以参照某个功能对应的这个属性类。

    1
    2
    3
    4
    5
    6
    7
    8
    // 从配置文件中获取指定的值和bean的属性进行绑定
    @ConfigurationProperties(prefix = "spring.http")
    public class Httpimport org.springframework.web.bind.annotation.RestController;
    {
    public static class Encoding {
    public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
    }
    }

作用

  • 在了解了springboot2自动配置过程后,添加其他框架进行配置和使用时,可以通过查找相关框架的xxxxAutoConfiguration和xxxxProperties类来了解与springboot2的配合使用。

@Conditional注解扩展

@Conditional扩展注解 作用(判断是否满足当前指定条件)
@ConditionalOnJava 系统中的java版本是否符合要求
@ConditionalOnBean 容器中存在指定的bean
@ConditionalOnMIssingBean 容器中不存在指定的bean
@ConditionalOnExpression 满足SpEl表达式
@ConditionalOnClass 系统中有指定的类
@ConditionalOnMIssingClass 系统中没有指定的类
@ConditionalOnSingleCandidate 容器中只有一个指定的bean,或者这个bean是首选
@ConditionalOnProperty 系统中指定的属性是否有值
@ConditionalOnResource 类路径下是否存在指定资源文件
@ConditionalOnWebApplication 当前环境是web环境
@ConditionalOnNotWebApplication 当前环境不是web环境
@ConditionalOnJndi JNDI存在指定项
zcolder wechat
写得不好?加我QQ开始喷我!