「Spring Boot 源码研究 」- 自动化装配条件化配置Conditional剖析
1. Spring Boot Condition功能与作用
@Conditional是源码研究基于条件的自动化配置注解, 由Spring 4框架推出的自动新特性 。
在一个服务工程 ,化装 通常会存在多个配置环境 ,配条配置l剖 比如常见的源码研究DEV(开发环境) 、SIT(系统内部集成测试环境) 、自动UAT(用户验收测试环境)、化装PRD(生产环境)等 。配条配置l剖在Spring3系列版本中通过@Profile实现,源码研究传入对应的自动环境标识 , 系统自动加载不同环境的化装配置。spring4版本正式推出Condition功能 ,配条配置l剖 在spring5版本,源码研究 @Profile做了改进,自动底层是化装通过Condition实现, 看下Condition接口的UML结构:
可以看到两个抽象类应用实现了Condition接口, 一个是Spring Context下的ProfileCondition , 另一个就是SpringBootCondition。
SpringBootCondition下面有很多实现类 ,也是满足Spring Boot的各种Condition需要 , 图中只是列出了部分实现, 每个实现类下面 , 都会有对应的注解来协助处理。
2. Conditional条件化系列注解介绍
Conditional的注解
Conditional的处理类
Conditional的说明
@ConditionalOnBean
OnBeanCondition
Spring容器中是否存在对应的实例 。可以通过实例的类型、类名 、注解 、昵称去容器中查找(可以配置从当前容器中查找或者父容器中查找或者两者一起查找)
@ConditionalOnClass
OnClassCondition
类加载器中是否存在对应的类。可以通过Class指定(value属性)或者Class的全名指定(name属性)如果是多个类或者多个类名的话,关系是”与”关系,也就是说这些类或者类名都必须同时在类加载器中存在
@ConditionalOnExpression
OnExpressionCondition
判断SpEL 表达式是否成立
@ConditionalOnMissingBean
OnBeanCondition
Spring容器中是否缺少对应的实例。可以通过实例的类型 、类名、注解、昵称去容器中查找(可以配置从当前容器中查找或者父容器中查找或者两者一起查找)
@ConditionalOnMissingClass
OnClassCondition
跟ConditionalOnClass的处理逻辑一样 ,只是条件相反,在类加载器中不存在对应的类
@ConditionalOnProperty
OnPropertyCondition
应用环境中的屬性是否存在 。提供prefix、name、havingValue以及matchIfMissing属性。prefix表示属性名的前缀 ,name是属性名,havingValue是具体的属性值 ,matchIfMissing是个boolean值,如果属性不存在,这个matchIfMissing为true的话,会继续验证下去,否则属性不存在的话直接就相当于匹配不成功
@ConditionalOnResource
OnResourceCondition
是否存在指定的资源文件 。只有一个属性resources ,是个String数组 。会从类加载器中去查询对应的资源文件是否存在
@ConditionalOnSingleCandidate
OnBeanCondition
Spring容器中是否存在且只存在一个对应的实例 。只有3个属性value、type、search 。跟ConditionalOnBean中的这3种属性值意义一样
@ConditionalOnWebApplication
OnWebApplicationCondition
应用程序是否是Web程序 ,没有提供属性 ,只是一个标识 。会从判断Web程序特有的类是否存在,环境是否是Servlet环境 ,容器是否是Web容器等
SpringBootCondition下面包含的主要条件化注解说明:
- @ConditionalOnBean: 当Spring容器存在某个Bean则触发实现。
- @ConditionalOnMissingBean: 当Spring容器不存在某个Bean则不触发 。
- @ConditionalOnSingleCandidate : 当Spring容器中只有一个指定Bean ,或者多个时是首选 Bean 。
- @ConditionalOnClass : 当环境路径下有指定的类, 则触发实现 。
- @ConditionalOnMissingClass: 当环境路径下没有指定类则不触发实现 。
- @ConditionalOnProperty:判断属性如果存在指定的值则触发实现 。
- @ConditionalOnResource: 判断存在指定的资源则触发实现 。
- @ConditionalOnExpression:基于 某个SpEL 表达式作判断实现 。
- @ConditionalOnJava:基于JDK的版本作判断实现。
- @ConditionalOnJndi :基于指定的 JNDI 作判断实现。
- @ConditionalOnNotWebApplication:判断当前项目定义如果不是 Web 应用则不触发实现 。
- @ConditionalOnWebApplication