标签:spring 配置 boot springframework 自动 org 原理 class
那些属性可以在配置文件中写呢: 参考官方文档:https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/htmlsingle/#common-application-properties 具体:Part X. Appendices Appendix A. Common application properties自动配置原理: 1.springboot在启动时加载著配置类(@SpringBootApplication标注的类),开启了自动配置功能(@EnableAutoConfiguration) 2.@EnableAutoConfiguration的作用:
1.@EnableAutoConfiguration标签的代码如下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage------------------>自动扫描启动类包下和其子包下的所有带标签的组件
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
...
}
2.AutoConfigurationImportSelector的代码如下:
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
...
//获取候选配置
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
....
}
3.getCandidateConfigurations的代码如下:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
//第一个参数返回:EnableAutoConfiguration.class
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
}
4.loadFactoryNames代码如下:
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
5.loadSpringFactories代码如下:
{
...
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
...
}
总结:发现其底层是获取jar类路径下的: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,\
...很多很多!
每一个这样的xxxAutoConfiguration都是容器的一个组件,都加到容器中,用他们来做自动配置!
springboot的精髓:
1.springboot启动时会加载大量的自动配置类(xxxAutoConfiguration) 2.我们看我们需要的功能有没有springboot默认写好的自动配置类 3.我们再来看这个自动配置类中到底配置了哪些组件(只要我们要用的组件有,就不需要再来配置了) 4.给容器中自动配置类添加组件时,会从properties类中获取某些属性值。我们就可以在配置文件中指定这些属性的值4 xxxAutoConfiguration:自动配置类 给容器中添加组件 xxxProperties:封装了配置文件中相关的属性 以HttpEncodingAutoConfiguration来理解其底层的(http编码自动设置)为例解释自动配置原理:@Configuration( //表示这是一个配置类,跟以前编写的配置文件一样(<bean></bean>)也可以给容器中添加组件
proxyBeanMethods = false
)
@EnableConfigurationProperties({ServerProperties.class})//启动指定类的ConfigurationProperties功能;将配置文件中的值和ServerProperties绑定起来
//判断当前类是不是web应用,如果是,当前配置类生效
@ConditionalOnWebApplication(//里面是spring的@Conditional(条件判断注解),根据不同的条件,如果满足指定的条件,配置类中的配置就会生效
type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class})//判断当前项目有没有这个类:CharacterEncodingFilter;springmvc中进行乱码解决的过滤器
@ConditionalOnProperty(//判断当前项目是否存在某个配置:server.servlet.encoding.enabled; 如果不存在,判断也是成立的()matchIfMissing = true),
//即使我们的配置文件中不配置server.servlet.encoding.enabled=true,也是默认生效的
prefix = "server.servlet.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
//这个Encoding 类是ServerProperties的内部类,所以和springboot的appliaction.properties文件以形成了映射关系(重要!)
private final Encoding properties;
@Bean//给容器中添加一个组件,这个组件的某些值要从properties中获取
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.RESPONSE));
return filter;
}
}
根据当前不同的条件判断,决定这个配置类是否生效!!
细节 1.@Conditional派生注解(spring注解版的原生的@Conditional的作用) 作用:是必须@Conditional指定的条件必须成立,才能给容器中添加组件,配置里面的内容才能生效
@Conditional扩展注解 | 作用(判断是否满足当前条件) |
@ConditionalOnjava | 系统的java版本是否满足要求 |
@ConditionalOnBean | 容器中存在指定的bean |
@ConditionalOnMissingBean | 容器中不存在指定的bean |
@ConditionalOnExpression | 满足SPEL表达式的 |
@ConditionalOnClass | 系统中存在指定的类 |
@ConditionalOnMissingClass | 系统中不存在指定的class |
@ConditionalOnSingleCandidate | 容器中只有一个指定的bean,或者这个bean是首选的bean |
@ConditionalOnProperty | 系统中指定的属性是否存在指定的值 |
@ConditionalOnResource | 类路径下是否存在指定的资源文件 |
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:(自动配置类启动的)
-----------------
AopAutoConfiguration matched:
- @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)
AopAutoConfiguration.ClassProxyingConfiguration matched:
- @ConditionalOnMissingClass did not find unwanted class 'org.aspectj.weaver.Advice' (OnClassCondition)
- @ConditionalOnProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition)
。。。。
Negative matches:(自动配置类没有匹配上的)
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)
AopAutoConfiguration.AspectJAutoProxyingConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.aspectj.weaver.Advice' (OnClassCondition)
....
标签:spring,配置,boot,springframework,自动,org,原理,class 来源: https://www.cnblogs.com/wmd-l/p/16250964.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。