SpringBoot 配置原理

自动配置原理

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

  2、 @EnableAutoConfiguration的作用

      1)、利用AutoConfigurationImportSelector类给容器导入一些组件

      2)、AutoConfigurationImportSelector这个类里面调用了selectImports()方法的的getAutoConfigurationEntry()方法的核心 

          List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); 获取候选配置

      3)、点进这个方法中,它调用了loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());方法。

        这个方法的作用就是扫描所有的jar包类路径下的META-INF/spring.factories 把扫描到的这些文件内容包装成properties对象

        从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把它们添加在容器中

      一句话讲,就是讲类路径下的 META-INF/spring.factories里面配置的所有EnableAutoConfiguration的值加入到容器中

      每一个这样的xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用它们来做自动配置

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

@Configuration(proxyBeanMethods = false) // 表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件
@EnableConfigurationProperties(HttpProperties.
class) // 启动指定的类ConfigurationProperties功能;
                                //将配置文件中对应的值和HttpEncodingProperties绑定起来
@ConditionalOnWebApplication(type
= ConditionalOnWebApplication.Type.SERVLET) // 判断当前应用是否是web应用,如果是,当前配置类生效
                            //底层是Spring的@Conditional注解,根据不同的条件,满足条件的配置类才会生效

@ConditionalOnClass(CharacterEncodingFilter.
class)// 判断当前项目有没有这个类 CharacterEncodingFilter:SpringMVC中进行乱码解决过滤器
@ConditionalOnProperty(prefix
= "spring.http.encoding", value = "enabled", matchIfMissing = true)// 判断我们配置文件中是否存在某个配置
      // spring.http.encoding.enable; matchIfMissing=true表示如果不存在,判断也是成立的
      // 即使我们文件中不配置spring.http.encoding.enable=true,也是默认生效的!
public class HttpEncodingAutoConfiguration {
  // 已经和SpringBoot的配置文件映射了
  
private final HttpProperties.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(Type.REQUEST));
  filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
  return filter;
  }
  .....
}
 

 

posted @ 2020-05-29 16:50  遨游java  阅读(228)  评论(0编辑  收藏  举报