SpringBoot原理发现(二)

 

说明:

本系列基于SpringBoot 2.2.9.RELEASE 版本,对SpringBoot的原理进行分析,一共分为四节:

SpringBoot原理发现(一):创建Hello World,对pom依赖以及@SpringBootApplication注解进行分析

SpringBoot原理发现(二):分析SpringBoot自动配置原理

SpringBoot原理发现(三):通过主配置类main方法分析SpringBoot启动配置原理

SpringBoot原理发现(四):了解SpringBoot启动中的几个重要回调机制
 

自动配置原理

 1. 自动配置源头

  @EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

  通过 SpringBoot原理发现(一)可以得出:

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

  2)@EnableAutoConfiguration的作用:

         A. @AutoConfigurationPackage:自动配置包,扫描主配置类所在包路径下面的所有组件并初始化进容器

      B. @Import(AutoConfigurationImportSelector.class) :通过源码,可以看出它是去扫描所有jar包类路径下面的 META-INF/Spring.factories,并返回EnableAutoConfiguration.class指定的值列表,并添加至容器中,如下图:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\

......

  上面的每一个XXXAutoConfiguration就是一个组件,它们的作用就是进行自动配置功能。

 2. 配置文件配置属性

  打开spring-boot-autoconfigure-2.2.9.RELEASE.jar/META-INF/spring.factories文件,找到其中的EnableAutoConfiguration类指定的值,以HttpEncodingAutoConfiguration为例

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {

  其他注解略过..

 2.1 @EnableConfigurationProperties(HttpProperties.class)

   开启HttpProperties.class)的配置属性功能,进入HttpProperties,可以看到如下代码:

@ConfigurationProperties(prefix = "spring.http")
public class HttpProperties {

  @ConfigurationProperties(prefix = "spring.http"):该注解是从配置文件中获取spring.http的值和Bean的属性进行绑定。

  而有哪些属性可配置在配置文件中就可以参考当前Bean拥有的属性。

  yml文件:

spring:
  http:
    encoding:
      charset: gbk

  通过debug如下代码:

@SpringBootApplication
public class DemoApplication {

    @Autowired
    private CharacterEncodingFilter characterEncodingFilter;

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
/**
 * HttpEncodingAutoConfiguration.class
 */
@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;
}

 yaml文件中设置的GBK,自动和HttpProperties的属性进行了绑定

所以配置文件中能配置哪些属性,就可以查看XXXProperties类的属性进行配置。

观察其他的XXXAutoConfiguration,如:RedisAutoConfiguration , CacheAutoConfiguration

都能发现 @EnableConfigurationProperties(XXXProperties.class)

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

可以发现,SpringBoot有很多这种模式:

 

  

 

posted @ 2020-11-02 14:01  swayer  阅读(173)  评论(0编辑  收藏  举报