自动配置原理:
1. SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration2. @EnableAutoConfiguration的作用: 给容器中导入组件
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
//最终通过一个 configurations 获取候选配置
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);<br/>
//loadFactoryNames
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
//loadFactoryNames 扫描类路径下的所有包 META-INF/spring.factories
public static final String FACTORIES_RESOURCE_LOCATION = "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.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,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
- 每一个这样的xxAutoConguration类都是容器中的一个组件,都加入到容器中,用他们来做自动配置
每一个自动配置类进行自动配置功能 - 以 HttpEncodingAutoConfiguration 为例子说明自动配置原理
@Configuration//表示这是一个配置类,给容器中添加组件
@EnableConfigurationProperties({HttpProperties.class})//启动指定类 @EnableConfigurationProperties 功能
@ConfigurationProperties功能:将配置文件对应的值和HttpProperties绑定起来
Spring底层@Conditional注解,根据不同条件,如果满足指定的条件,整个配置就会生效
@ConditionalOnWebApplication(//判断当前应用是否为Web应用,若是,当前配置类生效
type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class})//判断当前项目有没有这个类
CharacterEncodingFilter:SpringMVC 中解决乱码的过滤器
即使不配置 spring.http.encoding.enable 默认也是生效的
@ConditionalOnProperty(//判断是否存在某个配置 spring.http.encoding.enable
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true 不存在 判断也是成立的
)
给容器中添加一个组件,这个组件的某些值需要从properties中获取
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
return filter;
点击properties 内容如下//他已经和Springboot配置文件映射了
private final Encoding properties;
//只有一个有参构造器时,参数就会从容器中拿取
public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
}
}
}
- 所有的配置文件能配置的属性都在xxProperties类中封装着
@EnableConfigurationProperties({HttpProperties.class})//启动指定类 @EnableConfigurationProperties 功能
HttpProperties.class类
//从配置文件中获取指定的值和bean属性进行绑定
@ConfigurationProperties(
prefix = "spring.http"
)
public class HttpProperties {
private boolean logRequestDetails;
private final HttpProperties.Encoding encoding = new HttpProperties.Encoding();
public HttpProperties() {
}
//可以配置的属性
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;
}
总结:
7. SpringBoot启动会加载大量的自动配置类8. 我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;
9. 我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)
10. 给容器中自动配置类添加组件的时候,
11. 会从properties类中获取某些属性。我们就可以在配置文件中指定这 些属性的值;
xxxxAutoConfigurartion:自动配置类;
给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
@Conditional 派生注解
@Conditional扩展注解 作用(判断是否满足当前指定条件)@ConditionalOnJava 系统的java版本是否符合要求
@ConditionalOnBean 容器中存在指定Bean;
@ConditionalOnMissingBean 容器中不存在指定Bean;
@ConditionalOnExpression 满足SpEL表达式指定
@ConditionalOnClass 系统中有指定的类
@ConditionalOnMissingClass 系统中没有指定的类
@ConditionalOnSingleCandidate 容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty 系统中指定的属性是否有指定的值
@ConditionalOnResource 类路径下是否存在指定资源文件
@ConditionalOnWebApplication 当前是web环境
@ConditionalOnNotWebApplication 当前不是web环境
@ConditionalOnJndi JNDI存在指定项