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

2)@EnableAutoConfiguration作用

  • 利用EnableAutoConfigurationImportSelector给容器中导入一些组件。
  • 可以查看selectImports()方法的内容
  • List configurations=getCandidateConfigurations(annnotationMetadata,attributes);获取后选的配置
SpringFactoriesLoader.loadFactoryNames()
扫描所有jar包类路径下 META‐INF/spring.factories
把扫描到的这些文件的内容包装成properties对象
从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器
中

将类路径下META-INF/Spring.factories里面配置的所有EnableAutoConfiguration的值加入到容器中。

# 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.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,
\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration
,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration
,\

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

3)每一个自动配置类进行自动配置功能

4)以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理

@Configuration //表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件
@EnableConfigurationProperties(HttpEncodingProperties.class) //启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把 HttpEncodingProperties加入到ioc容器中
@ConditionalOnWebApplication
//Spring底层@Conditional注解(Spring注解版),根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效; 判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnClass(CharacterEncodingFilter.
class) //判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnProperty(prefix
= "spring.http.encoding", value = "enabled", matchIfMissing =true) //判断配置文件中是否存在某个配置 spring.http.encoding.enabled;如果不存在,判断也是成立的 //即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的; public class HttpEncodingAutoConfiguration { //他已经和SpringBoot的配置文件映射了 private final HttpEncodingProperties properties; //只有一个有参构造器的情况下,参数的值就会从容器中拿 public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) { this.properties = properties; }
@Bean
//给容器中添加一个组件,这个组件的某些值需要从properties中获取 @ConditionalOnMissingBean(CharacterEncodingFilter.class) //判断容器没有这个组件? 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类中获取的,这些类里面的每一个属性又是和配置文件绑定的。

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

@ConfigurationProperties(prefix = "spring.http.encoding") //从配置文件中获取指定的值和bean的属性进行绑定
public class HttpEncodingProperties {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF‐8");

总结:

  1. SpringBoot启动会加载大量的自动配置类
  2. 我们看我们需要的功能有没有SpringBoot默认写好的自动配置类
  3. 我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)
  4. 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性,我们就可以在配置文件中指定这些属性的值

XXXAutoConfiguration:自动配置类,给容器中添加组件。

XXXProperties:封装配置文件中相关属性

细节

@Conditional派生注解(Spring注解版原生的@Conditional作用)

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效。

 自动配置类必须在一定的条件下才能生效

可以通过启用debug=true属性,来让控制台打印自动配置报告,这样就可以方便的知道哪些自动配置类生效。

 

 

具体分析

@SpringBootApplication是一个复合注解或派生注解,在@SpringBootApplication中有一个注解@EnableAutoConfiguration,该注解就是开启自动配置。

 

 @EnableAutoConfiguration也是一个派生注解,其中的关键功能由@Import提供,其导入的AutoConfigurationImportSelector的selectImport()方法通过SpringFactoriesLoader.loadFactoryNames()扫描所有具有META-INF/spring.factories的jar。spring-boot-autoconfigure-X.X.X.X.jar里就有一个这样的spring.factories文件。

这个spring.factories文件也是一组一组的key=value的形式,其中一个key是EnableAutoConfiguration类的全类名,而它的value是一个XXXAutoConfiguration的类名的列表,这些类名以逗号分隔。

 这个@EnableAutoConfiguration注解通过@SpringBootApplication被间接的标记在了Spring Boot的启动类上,在SpringApplication.run(..)的内部就会执行selectImports()方法,找到所有javaConfig自动配置类的全限定名对应的class,然后将所有自动配置类加载到Spring容器中。

自动配置生效

每个XXXAutoConfiguration自动配置类都是在某些条件之下才会生效的,这些条件的限制在Spring Boot中以注解的形式体现。

 

以ServletWebServerFactoryAutoCofiguration配置类为例,解释全局配置文件中的属性如何生效如:server.port=8082

 在ServletWebServerFactoryAutoConfiguration类上,有一个@EnableConfigurationProperties注解:开启配置属性。后面的参数是一个ServerProperties类

 

 在这个类上,看到了一个非常熟悉的注解:@ConfigurationProperties,它的作用就是从配置文件中绑定属性到对应的bean上,而@EnableConfigurationProperties负责导入这个已经绑定了属性的bean到spring容器。那么所有其他的和这个类相关的属性都可以在全局配置文件中定义,也就是说,真正”限制“我们可以在全局配置文件中配置哪些属性的类就是这些XXXProperties类,它与配置文件中定义的prefix关键字开头的一组属性是唯一对应的。

至此,可以了解,在全局配置的属性如:server.port等,通过@ConfigurationProperties注解,绑定到对应的XXXProperties配置实体类上封装为一个bean,然后再通过@EnableConfigurationProperties注解导入到Spring容器中。

而诸多XXXAutoConfiguration自动配置类,就是Spring容器的javaConfig形式,作用就是为Spring容器导入bean,而所有导入的bean所需要的属性都通过XXXProperties的bean来获得。

总结:

      Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类,它能通过以Properties结尾名命名的类中取得全局配置文件中配置的属性值,而XXXProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。

 

自动配置流程图

 

 posted on 2020-11-26 17:09  会飞的金鱼  阅读(142)  评论(0)    收藏  举报