【SpringBoot】很好用的一组 Condition —— AllNestedConditions AnyNestedCondition NoneNestedConditions
前言
SpringBoot 对 @Conditional 注解的拓展是十分漂亮的,也是 SpringBoot 式 API 设计 的代表作,本文介绍几个很好用的 Condition 拓展类,在这之前如果想要了解一下 Conditon 相关,可以阅读下文
【源码】Spring —— Condition 条件匹配解读
【源码】SpringBoot 对 Condition 的拓展 —— @ConditionalOnXxx系列注解
关于什么叫做 SpringBoot 式 API 设计,这是我个人的理解:
Spring 式 API,java API 设计的天花板,简单、优雅,最重要的是拥有
无限的生命力(易拓展,不然也不会有 SpringBoot 了),“简单” 是指逻辑的
实现相对简单(设计可一点都不简单)而且代码伴随着大量的注解,因此想潜心看
还是有可能看懂的
SpringBoot 式 API,同样是 java API 设计的天花板,但是逻辑实现是
真的复杂,且伴随着 天马行空 的想象力,编码风格逐渐向 函数式编程 靠
拢,且因为代码注解相对 Spring 少的多了,因此我认为逻辑能力如果不够强
且没有足够的时间,真的看不懂一些 API 的实现逻辑(反正我看不懂,光一个
Binder 我看了一周没看明白,放弃了)
不废话,直接上干货
AllNestedConditions
AllNestedConditions, 该类本身就是一个 Condition,因此可以直接作为条件注解 @Conditonal 的 value,但是它可以包含一组 Condition,且当前目标类要 match 这些所有 Conditon,才会被注册进去
如果不好理解,直接看示例
@Configuration
public class ConditionConfig {
@Bean
@Conditional(BorCCondition.class)
public BorC borC() {
return new BorC();
}
static class BorCCondition extends AllNestedConditions {
public BorCCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnBean(B.class)
class BCondition {
}
@ConditionalOnBean(C.class)
class CCondition {
}
}
@Configuration
static class Config {
@Bean
public B b() {
return new B();
}
}
}
示例中的 BorCCondition 包含了一组 Conditon,其中 BCondition 是容器中要有 B 的 bean实例,CConditon 亦然,同时 BorCCondition 是一个 AllNestedConditions,因此只有当 BCondition 和 CConditon 全都 match 时,BorC 的 bean实例 才会被注册到容器中
至于为什么命名 BorCCondition 是因为我一开始写的 demo 是 AnyNestedCondition
如上示例中,BorC 的 bean实例 不会被注册,可以自己动手试试
AnyNestedCondition
这就不难理解了,只要 match 其中任意 Condition,目标实例就会被注册
NoneNestedConditions
只有不 match 所有 Conditon,目标实例才会被注册
总结
关于它们的实现逻辑其实可以自己想象一下,我并不打算深究 SpringBoot 的实现,原因见前言
这几种 Condition 在 SpringBoot 的装配类中十分常见,我就是在 LoadBalance 的装配类中开始感兴趣的,我们在日常开发的场景也难免会遇到这种需要组合条件匹配的 bean实例
@Conditonal 作为我第二喜欢的注解(第一是 @Configuration),只要有机会我就一定会使用它!