SpringBoot自动配置解析

SpringBoot自动配置源码

springboot启动加载主配置类,@SpringBootApplication下的@EnableAutoConfiguration注解开启自动配置

SpringBoot在启动的时候,从类路径下的META-INF/spring.factories中获取EnableAutoConfigurationn下的xxxAutoConfiguration值,将这些值作为自动配置类导入到容器中,用他们做自动配置,每一个自动配置类进行自动配置功能

@EnableAutoConfiguration:
利用@Import(AutoConfigurationImportSelector.class)给容器中导入组件

  1. AutoConfigurationImportSelector类中getCandidateConfigurations()方法
//获取候选的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
//扫描所有jar包类路径下 META-INF/spring.factories
//getSpringFactoriesLoaderFactoryClass()获取 EnableAutoConfiguration.class类
   List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
         getBeanClassLoader());
   Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
         + "are using a custom packaging, make sure that file is correct.");
   return configurations;
}
  1. 扫描到META-INF/spring.factories后,在SpringFactoriesLoader类中loadSpringFactories()方法
//把扫描到的spring.factories内容包装成properties对象
//从 properties中获取到 EnableAutoConfiguration.class类对应的值,添加到容器中
Enumeration<URL> urls = (classLoader != null ?
      classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
      ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
result = new LinkedMultiValueMap<>();
while (urls.hasMoreElements()) {
   URL url = urls.nextElement();
   UrlResource resource = new UrlResource(url);
   Properties properties = PropertiesLoaderUtils.loadProperties(resource);
   for (Map.Entry<?, ?> entry : properties.entrySet()) {
      String factoryTypeName = ((String) entry.getKey()).trim();
      for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
         result.add(factoryTypeName, factoryImplementationName.trim());
      }
   }
}
  1. EnableAutoConfiguration对应的值:每一个xxxAutoConfiguration都是容器的一个组件

在这里插入图片描述

以HttpEncodingAutoConfiguration为例:

根据当前不同的条件判断,决定这个配置类是否生效。 一但这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的xxxproperties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;

//表示这是一个配置类,也可以给容器中添加组件 
@Configuration

//启用指定类(ServerProperties)的 ConfigurationProperties功能
//所有在配置文件中能配置的属性都在xxxProperties类中封装
	ServerProperties类
	//从配置文件中获取指定的值,和bean属性进行绑定
	@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
	//定义的属性就是配置文件中可配置的值(server.port=8080)
	private Integer port;
//将配置文件的值和 ServerProperties绑定起来,并加入到容器中
@EnableConfigurationProperties(ServerProperties.class)

//Spring底层 @Conditional:根据不同的条件判断配置类是否满足指定条件,从而判断整个配置类是否生效
//判断当前应用是否为 web应用,如果是则当前配置类生效,否则不生效
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
//判断当前项目有没有指定类(CharacterEncodingFilter)
@ConditionalOnClass(CharacterEncodingFilter.class)
//判断配置文件中是否存在某个配置(server.servlet.encoding.enabled)
//matchIfMissing = true,不配置就默认为true
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)

public class HttpEncodingAutoConfiguration {
   //已经和配置文件映射过了
   private final Encoding properties;
   //只有一个有参构造器,将配置文件的properties赋值给此类中定义的properties
   //@EnableConfigurationProperties的作用
   public HttpEncodingAutoConfiguration(ServerProperties properties) {
      this.properties = properties.getServlet().getEncoding();
   }

   //给容器中添加组件,组件里的某些值需要从properties中获取
   @Bean
   @ConditionalOnMissingBean
   public CharacterEncodingFilter characterEncodingFilter() {
      CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
      filter.setEncoding(this.properties.getCharset().name());
      filter.setForceRequestEncoding(this.properties.shouldForce(Encoding.Type.REQUEST));
      filter.setForceResponseEncoding(this.properties.shouldForce(Encoding.Type.RESPONSE));
      return filter;
   }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值