Spring Boot启动的时候加载了主配置类,开启了自动配置功能@EnableAutoConfiguration。
@EnableAutoConfiguration的作用:
利用@Import({AutoConfigurationImportSelector.class})给容器导入了一些组件。可以查看selectImports方法的内容。
List<String> configurations
= this.getCandidateConfigurations(annotationMetadata, attributes);
该方法的作用是扫描所有jar包类路径下的META-INF/spring.factories。把扫描到的这些文件的内容包装成properties对象。从properties中获取到EnableAutoConfiguration.class类的类名对应的值,然后把它们添加在容器中。
将类路径下META-INF/spring-factories里配置的所有EnableAutoConfiguration的值加入到容器中。用它们做自动配置。
每一个自动配置类进行自动配置功能。
以HttpEncodingAutoConfiguration为例解释自动配置原理
@Configuration(
proxyBeanMethods = false
)
@EnableConfigurationProperties({HttpProperties.class})
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class})
@ConditionalOnProperty(
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
@Configuration:表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件。
@EnableConfigurationProperties:启动指定类的ConfigurationProperties功能。将配置文件中对应的值和HttpEncoding绑定起来了。并把这个类加入到IOC容器中。
在这个程序中我们指定的类是HttpProperties.class。我们能配置的属性都来自于这个类。
public static class Encoding {
public static final Charset DEFAULT_CHARSET;
private Charset charset;
private Boolean force;
private Boolean forceRequest;
private Boolean forceResponse;
private Map<Locale, Charset> mapping;
根据这个类我们可以这样写我们的配置文件:
spring.http.encoding.charset=utf-8
spring.http.encoding.force=true
...
@ConfigurationProperties(
prefix = "spring.http"
)
public class HttpProperties {
从配置文件中获取指定的值和bean的属性进行绑定。
所有在配置文件中能配置的属性都是在...properties类中封装着。配置文件能配置什么就可以参照某一个功能的属性类。
@ConditionalOnWebApplication:首先需要解释@Conditional标签。该标签根据不同的条件进行条件判断。如果满足指定的条件,指定的配置类中的配置才会生效。该标签的作用就是判断当前应用是否为web应用。
@ConditionalOnClass:判断当前项目有没有指定的类。
@ConditionalOnProperty:判断配置文件中是否存在某个配置。即使配置文件中不存在该配置,也是默认生效的。
根据当前不同的条件进行判断,决定这个配置类是否生效。给容器中添加一个组件。一旦这个配置类生效,这个配置类就会给容器中添加各种组件。这些组件的属性是从对应的propertises类中获取的。propertises中的每一个属性又是和配置文件绑定的。
Spring Boot的精髓:
- Spring Boot启动会加载大量的自动配置类。
- 我们需要看我们需要的功能有没有Spring Boot写好的自动配置类。
- 如果有这个自动配置类中配置了那些组件。只要有我们需要就组件,就不需要配置了。如果没有就需要我们自己写了。
- 给容器中的自动配置类添加组件时,会从properties中获取某些属性。我们就可以在配置文件中指定这些属性的值。
xxxAutoConfiguration:自动配置类
给容器中添加组件
xxxProperties:封装配置文件中的相关属性
细节
@Conditional派生注解(Spring注解版原生的@Conditional作用)
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置类里的所有内容才生效。
@Conditional扩展注解 | 作用(判断是否满足当前指定的条件) |
---|---|
@ConditionalOnJava | 系统的Java版本是否符合要求 |
@ConditionalOnBean | 容器中存在指定的Bean |
@ConditionalOnMissingBean | 容器中不存在指定的Bean |
@ConditionalOnExpression | 满足SpEL表达式指定 |
@ConditionalOnClass | 系统中有指定的类 |
@ConditionalOnMissingClass | 系统中没有指定的类 |
@ConditionalOnSingleCandidate | 容器中只有一个指定的Bean,或者这个Bean是首选Bean。 |
@ConditionalOnProperty | 系统中指定的属性是否有指定的值 |
@ConditionalOnResource | 类路径下是否存在指定资源文件 |
自动配置类必须在一定的条件下才能生效。
如何知道那些配置类生效:
在配置文件中写上
debug=true
控制台就会输出那些配置类使用了,那些配置类没有使用。控制台的输出结果中有positive matches表示那些类启动了,而negative matches表示没有匹配成功的自动配置类。