作用在 Spring Bean 或返回 Spring Bean 的方法上,符合条件的 Bean 才实例化并加载到 Spring 容器中
@Conditional 是 spring-context 包中的注解
在 Spring Boot(spring-boot-autoconfigure) 中大量使用
- ConditionalOnBean
- ConditionalOnClass
- ConditionalOnProperty
- ConditionalOnMissingBean
- ConditionalOnWebApplication
- …
1. 定义自己的条件注解 MyCondition,实现 Condition 接口
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String profiles = context.getEnvironment().getProperty("active.profiles");
return "dev".equals(profiles);
}
}
- 在 Run/Debug Configurations - VM Options 中,配置 -Dactive.profiles=dev
- Spring 初始化 Bean 前,ConditionEvaluator 会调用所有作用在当前 Bean 的 Condition 子类的 matches() 方法
2. 定义条件 Bean ConditionBean,并加上注解 @Conditional(MyCondition.class)
@Component
@Conditional(MyCondition.class)
public class ConditionBean {
public ConditionBean() {
System.out.println("ConditionBean init..");
}
}
3. 定义一个空的启动类,用于开启扫描
@ComponentScan
public class ConditionApp {
}
4. 测试
public class ConditionTest {
@Test
public void test01() {
new AnnotationConfigApplicationContext(ConditionApp.class);
}
}
// 打印结果
ConditionBean init..
5. SpringBoot 中的使用
- 定义一个新的注解 ConditionalOnDev
- @Conditional(MyCondition.class) 作用在新注解上
- 在需要条件的 Bean 上直接使用即可
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(MyCondition.class)
public @interface ConditionalOnDev {
}
// ************
@Component
@ConditionalOnDev
public class ConditionBean {
public ConditionBean() {
System.out.println("ConditionBean init..");
}
}