@Conditional
@Conditional的作用域:
1. 类级别可以放在注标识有@Component(包含@Configuration)的类上
2. 作为一个meta-annotation,组成自定义注解
3. 方法级别可以放在标识由@Bean的方法上
如果一个@Configuration的类标记了@Conditional,所有标识了@Bean的方法和@Import注解导入的相关类将遵从这些条件
自定义Conditional
自定义Conditional就是通过自定义注解和Condition的实现类
定义自定义注解@ConditionalOnMyAnnotation
@Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(OnMyCondition.class) public @interface ConditionalOnMyAnnotation { String name(); }
OnMyCondition,这里继承了SpringBootCondition重用了部分功能,然后在getMatchOutcome实现了自定义的功能
public class OnMyCondition extends SpringBootCondition { public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { Object propertiesName = metadata.getAnnotationAttributes(ConditionalOnMyAnnotation.class.getName()).get("name"); if (propertiesName != null) { String value = context.getEnvironment().getProperty(propertiesName.toString()); if (value != null) { return new ConditionOutcome(true, "get properties"); } } return new ConditionOutcome(false, "none get properties"); } }
或者直接实现Condition接口
public class OnMyCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Object propertiesName = metadata.getAnnotationAttributes(ConditionalOnMyAnnotation.class.getName()).get("name"); if (propertiesName != null) { String value = context.getEnvironment().getProperty(propertiesName.toString()); if (value != null) { return true; } } return false; }
- OnMyCondition使用类,还要加上Configuration注解才能生效
@Configuration @ConditionalOnMyAnnotation(name = "test") static class MyAnnotationConfiguration { @Bean @ConditionalOnMissingBean(Test.class) public Test test() { return new Test(); } }
常见条件注解
- @ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)
- @ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
- @ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)
- @ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)
- @ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
- @ConditionalOnNotWebApplication(不是web应用)