上一篇文章 你应该知道的 @ConfigurationProperties 注解的使用姿式,这一篇就够了 介绍了如何经过 @ConfigurationProperties
注解灵活读取配置属性,这篇文章将介绍如何灵活配置 Spring Beanjava
当咱们构建一个 Spring 应用的时候,有时咱们想在知足指定条件的时候才将某个 bean 加载到应用上下文中, 在Spring 4.0 时代,咱们能够经过 @Conditional
注解来实现这类操做git
咱们看到 @Conditional
注解接收的参数是 extends Condition 接口的泛型类,也就是说,咱们要使用 @Conditional
注解,只须要实现 Condition 接口并重写其方法便可:github
看到接口的 matches 方法返回的是 boolean 类型,是否是和咱们自定义 validation annotation 有些相似,都是用来判断是否知足指定条件。另外注意看,以上注解和接口都在 org.springframework.context.annotation
package 中web
终于到了 Spring Boot 时代,在这个全新的时代,Spring Boot 在 @Conditional
注解的基础上进行了细化,无需出示复杂的介绍信 (实现 Condition 接口),只须要手持预约义好的 @ConditionalOnXxxx
注解印章的门票,若是验证经过,就会走进 Application Context 大厅面试
Spring Boot 对 @Conditional
注解为咱们作了细化,这些注解都定义在 org.springframework.boot.autoconfigure.condition
package 下spring
逐个打开这 13 个注解,咱们发现这些注解上有相同的元注解:app
从这些标记上咱们能够了解以下内容:框架
@ConditionalOnXxxx
来判断是否加载@Conditional
注解来标记,OnBeanCondition 等自定义 Condition 仍是实现了 Condition 接口的,换汤不换药,没什么神秘的,只不过作了更具象的封装罢了,来看类依赖图:其实看这些注解字面意思已经能理解这些注解的含义,可是咱们仍是要说明具体的使用以及一些注意事项,我按照我的使用频次由高到低讲解:spring-boot
毫无疑问这个注解是榜首工具
这个条件解释是: application.properties 或 application.yml 文件中 mybean.enable 为 true 才会加载 MyCondition 这个 Bean,若是没有匹配上也会加载,由于 matchIfMissing = true,默认值是 false。
有时候咱们须要某个 Bean 已经存在应用上下文时才会加载,那么咱们会用到 @ConditionalOnBean
注解:
与之相反,有时候咱们须要某个 Bean 不存在于应用上下文时才会加载,那么咱们会用到 @ConditionalOnMissingBean
注解
不要嫌我废话,和上面的同样,只不过判断某个类是否存在于 classpath 中,这就不作过多说明了
若是咱们有更复杂的多个配置属性一块儿判断,那么咱们就能够用这个表达式了:
只有当两个属性都为 true 的时候才加载 MyModule,到这里要顺便揭晓上一篇文章 你应该知道的 @ConfigurationProperties 注解的使用姿式,这一篇就够了 灵魂追问 3,其中 :true
就是: 若是没有为该属性设置值,则为该属性设置默认值true, 其实这就是@Vaue
注解的规范,一切 SpEL 均可以应用在这里.
写到这,我经常使用的已经用完了,还要硬着头皮介绍其余几个内容 😄,开个玩笑,我们继续:
这个注解和 @ConditionalOnBean 相似,为了更好的说明该注解的使用 (实际上是 才疏学浅
) ,我只能翻译一下类的注释了
只有指定类已存在于 BeanFactory 中,而且能够肯定单个候选项才会匹配成功BeanFactory 存在多个 bean 实例,可是有一个 primary 候选项被指定(一般在类上使用
@Primary
注解),也会匹配成功。实质上,若是自动链接具备定义类型的 bean 匹配就会成功目前,条件只是匹配已经被应用上下文处理的 bean 定义,自己来说,强烈建议仅仅在 auto-configuration 类中使用这个条件,若是候选 bean 被另一个 auto-configuration 建立,确保使用该条件的要在其后面运行
若是咱们要加载的 bean 依赖指定资源是否存在于 classpath 中,那么咱们就可使用这个注解
看到这个 logback.xml 是否是很亲切,在咱们引入第三方工具类如 Dozer 等均可以添加相似的开关
接下来的是真冷门,你们有个印象,若是有须要,至少能想到用这些注解实现灵活配置就行了
只有指定的资源经过 JNDI 加载后才加载 bean
只有运行指定版本的 Java 才会加载 Bean
只有运行在 web 应用里才会加载这个 bean
与之相反,在非 web 环境才加载 bean
这个注解冷的我呼吸都要中止了,只有运行在指定的云平台上才加载指定的 bean,CloudPlatform 是 org.springframework.boot.cloud
下一个 enum 类型的类,你们能够打开自行看看:
到此,Spring Boot 为咱们提供的这 13 个注解就介绍完了,可是没有结束,下面的一些冷门知识,你须要知道:
若是咱们想多个条件一块儿应用,而且条件的关系是 and
,咱们只须要在类上使用多个@ConditionalOnXxxx
就能够了 (你这也叫冷门?) ,固然也能够继承 AllNestedConditions
类封装咱们多个条件
这样就有了组合 and 条件,只有内部全部条件都知足,才加载指定 bean
若是咱们但愿组合的条件是 or
的关系,咱们该怎么办呢? 咱们能够经过继承 AnyNestedCondition
来完成这一要求,示例代码和上面同样,你们自行打开 AnyNestedCondition
类,查看类说明便可
有 and 和 or 就确定有 non(非),咱们能够经过继承 NoneNestedConditions
完成这一要求,你们自行查看便可
## 自定义注解
经过组合方式实现了多条件逻辑应用,咱们须要应用这些组合条件也就要自定义注解,其实文章开头已经讲过了,模仿内置的 13 个注解写就行了:
只须要经过@Conditional
注解指定咱们自定义的 condition 类就行了,而后应用到你想用的地方就行了
仍是推荐你们看 RabbitMq 的 RabbitAutoConfiguration
类,这个类里面主流的注解都是用了 (只看这一个类就行了),你们看框架理解学习这些注解是更好的方式:
https://github.com/spring-pro...
到这里,你已经了解了如何灵活配置 bean,结合以前的文章,相信的定义会更加灵活,但愿你们打开 IDE,自行查看这些注解,了解更多具体内容
@Configuration @ConditionalOnClass(MyBean.class) public class MyConfiguration{ // omitted }
欢迎持续关注公众号:「日拱一兵」
- 前沿 Java 技术干货分享
- 高效工具汇总 | 回复「工具」
- 面试问题分析与解答
- 技术资料领取 | 回复「资料」
以读侦探小说思惟轻松趣味学习 Java 技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,请持续关注......