12.1、自定义Condition

tech2023-12-16  30

1、 @Conditional 注解

基于条件的注解,它的作用是根据是否满足某个特定条件来决定是否创建某个特定的Bean,他是Spring Boot 实现自动配置的基础能力

Indicates that a component is only eligible for registration when all specified conditions match. 指示组件只有在所有指定条件匹配时才有资格注册。 A condition is any state that can be determined programmatically before the bean definition is due to be registered (see Condition for details). 条件是在注册bean定义之前可以通过编程方式确定的任何状态(详细信息请参阅条件)。 The @Conditional annotation may be used in any of the following ways: @Conditional注释可以用以下几种方式使用: as a type-level annotation on any class directly or indirectly annotated with @Component, including @Configuration classes as a meta-annotation, for the purpose of composing custom stereotype annotations as a method-level annotation on any @Bean method If a @Configuration class is marked with @Conditional, all of the @Bean methods, @Import annotations, and @ComponentScan annotations associated with that class will be subject to the conditions. 类型层次注释在任何类直接或间接与@component注释,包括元注释@configuration类编写自定义原型为目的的任何@bean注释的方法级注释方法 如果标有@configuration@Conditional, @bean方法,所有的注释 @import, @ComponentScan注释相关的类将受到条件。 NOTE: Inheritance of @Conditional annotations is not supported; 注意:不支持继承@Conditional注释; any conditions from superclasses or from overridden methods will not be considered. 来自超类或覆盖方法的任何条件都将不被考虑。 In order to enforce these semantics, @Conditional itself is not declared as @Inherited; 为了加强这些语义,@Conditional本身没有被声明为@Inherited; furthermore, any custom composed annotation that is meta-annotated with @Conditional must not be declared as @Inherited. 此外,任何用@Conditional元注释的自定义组合注释都不能声明为@Inherited@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Conditional { /** * All {@link Condition}s that must {@linkplain Condition#matches match} * in order for the component to be registered. */ Class<? extends Condition>[] value(); }

2、常见Conditional注解

2.1、ConditionalOnBean

当容器中有指定的 Bean 才开启配置,如何实现的呢?内部原理是什么?

@Conditional(OnBeanCondition.class) public @interface ConditionalOnBean { ... }

2.2、ConditionalOnClass

@Conditional(OnClassCondition.class) public @interface ConditionalOnClass { ... }

2.3、ConditionalOnMissingBean

@Conditional(OnBeanCondition.class) public @interface ConditionalOnMissingBean { ... }

2.4、ConditionalOnNotWebApplication

@Conditional(OnWebApplicationCondition.class) public @interface ConditionalOnNotWebApplication { ... }

2.5、ConditionalOnProperty

@Conditional(OnPropertyCondition.class) public @interface ConditionalOnProperty { ... }

2.6、ConditionalOnJava

public @interface ConditionalOnJava { ... }

2.7、ConditionalOnWebApplication

public @interface ConditionalOnWebApplication { ... }

2.8、ConditionalOnNotWebApplication

@Conditional(OnWebApplicationCondition.class) public @interface ConditionalOnNotWebApplication { ... }

3、自定义@Conditional注解

@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) @Documented @Conditional(FirstCondition.class) public @interface FirstConditionAnnotation { String[] values() default{}; } public class FirstCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Map<String, Object> valueMap = metadata.getAnnotationAttributes(FirstConditionAnnotation.class.getName()); String[] propertykeys = (String[])valueMap.get("values"); for (String key : propertykeys) { String value = context.getEnvironment().getProperty(key); if (StringUtils.isEmpty(value)) { return false; } } return true; } } @Component @FirstConditionAnnotation(values={"firstCondition1","firstCondition2"}) public class FirstConditionBean { }
最新回复(0)