日拱一卒,功不唐捐。

在了解 @Conditional 之前先花 10 秒钟复习一下 @Configuration 这个注解。

@Configuration 是干什么?

是配合 @Bean 注解来配置 Spring 容器的 bean 的。

那它为什么会出现呢?

因为配置 bean 的另一种方式是 xml ,狗都不用。

那给个示例看看呗?

简单。

@Configuration
public class AppConfig {
    @Bean
    public MyBean myBean() {
        // 初始化, 配置, 返回bean...
    }
}

下面进入主题:

@Conditional 是什么东西?

首先明确第一点:

@Conditional 是
Spring
提供的。

其次明确第二点:

Conditional 中文译为:
有条件的,依...而定的。

前边既然讲了 @Configuration 的简单用法,那么问题就是:

@Configuration + @Conditional 有没有搞头?

有搞头。

怎么搞?

那就是可以给@Configuration加上一个开关。

我打开开关,你这配置就好用。

我关闭开关,你这配置就不好用。

进一步升级。

我给 @Configuration 里的 @Bean 加一个开关。

我打开开关,你这 bean 就注册。

我关闭开关,你这 bean 就不注册。

那开关在哪里呢?

废话不多说,先上代码。

@Configuration
@Conditional(MyCondition.class)
public class ConditionConfig {
    @Bean
    public ConditionBean conditionBean() {
        return new ConditionBean();
    }
}

开关就是代码中的
MyCondition.class

WTF is MyCondition.class ?

MyCondition类就是我们自定义的开关,我们定义什么时候开,什么时候关的逻辑。

很明显这个逻辑不可能是 Spring 给的。

但 Spring 又必须插手管理。

通过什么呢?

没错,通过
接口 Condition

这个接口中什么都没有,只有一个
matches
方法,返回一个 boolean 值。

显而易见,你返回 true, 开关打开,返回 false,开关关闭。

MyCondition 类代码如下:

    public class MyCondition implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return true;
        }
    }

可以看到 matches 方法中的两个参数,可以简单介绍一下。

ConditionContext context
这个参数提供了一种方法来访问关于Spring容器的信息。

AnnotatedTypeMetadata metadata
这个参数提供了对被注解类的元数据的访问。

基于这两个参数我们就可以
创建复杂和动态的条件来控制开关的闭合

例如,你可以基于环境变量、定义的bean、类的存在等因素,来决定是否创建某个bean。

除了自定义 Condition,Springboot 还为我们扩展了一些常用的 Condition。


标签: none

添加新评论