Spring

Spring条件注解说明

2019-08-03  本文已影响2人  王勇1024

条件判断

@Conditional

@Conditional是Spring4新提供的注解,它的作用指定一个或多个实现了Condition接口的类,只有满足这些类的所有matches()方法中的条件时,才会注册当前bean。
该注解可以用在类或方法上,用于控制bean的注册。用在方法上时,通常与@Bean一起使用。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    // 需要指定一个或多个实现了Condition接口的类,
    // 只有满足这些类的所有matches()方法中的条件时,才会注册当前bean
    Class<? extends Condition>[] value();

}

Condition接口定义如下:

@FunctionalInterface
public interface Condition {
    // 判断是否满足条件
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

@ConditionalOnBean

只有在满足所有指定要求的bean已经包含在BeanFactory中时才匹配。 要匹配的条件必须满足所有要求,但当前的bean不必满足它们。
该注解可以用在类或方法上,用于控制bean的注册。用在方法上时,通常与@Bean一起使用。
从下面该注解的声明可以看到,该注解的实现是依赖@Conditional(OnBeanCondition.class)的。

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class)
public @interface ConditionalOnBean {
    // 按照Bean Class进行匹配
    Class<?>[] value() default {};
    // 按照Bean Class名称进行匹配
    String[] type() default {};
    // 按照Bean包含的注解进行匹配
    Class<? extends Annotation>[] annotation() default {};
    // 按照Bean的名称进行匹配
    String[] name() default {};
    // 搜索策略,是否考虑Context的层级关系(parent context)
    SearchStrategy search() default SearchStrategy.ALL;
    // 可能在其泛型参数中包含指定bean类型的其他类
    Class<?>[] parameterizedContainer() default {};

}

搜索策略

public enum SearchStrategy {
    // 只搜索当前的Context
    CURRENT,
    // 搜索所有的祖先Context,但不包含当前Context
    ANCESTORS,
    // 搜索所有的层级
    ALL
}

@ConditionalOnMissingBean

@ConditionalOnBean判断的规则正好相反,当所有指定要求的bean不包含在BeanFactory中时才匹配。
当该注解用于一个有@Bean注解的方法时,该注解的判断条件默认为该方法的返回值类型。

@Configuration
public class MyAutoConfiguration {
     @ConditionalOnMissingBean
     @Bean
     public MyService myService() {
         ...
     }
}

@ConditionalOnWebApplication

当当前应用为Web类型时,该方法才匹配。默认情况下匹配所有的Web类型,也可以通过type字段指定要匹配的Web应用类型。

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnWebApplicationCondition.class)
public @interface ConditionalOnWebApplication {
    // 匹配的Web应用类型
    Type type() default Type.ANY;
    // 可支持的应用类型
    enum Type {
        // 匹配任意Web应用类型
        ANY,
        // 只匹配Servlet Web应用类型
        SERVLET,
        // 只匹配“响应式”Web应用类型
        REACTIVE
    }
}

@ConditionalOnProperty

通过其两个属性name以及havingValue来实现的,其中name用来从application.properties中读取某个属性值。
如果该值为空,则返回false;
如果值不为空,则将该值与havingValue指定的值进行比较,如果一样则返回true;否则返回false。
如果返回值为false,则该configuration不生效;为true则生效。

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnPropertyCondition.class)
public @interface ConditionalOnProperty {
    // name属性的别称
    String[] value() default {};
    // property名称的前缀,可有可无
    String prefix() default "";
    // 数组,property完整名称或部分名称(可与prefix组合使用,组成完整的property名称),与value不可同时使用
    String[] name() default {};
    // 指定properties期望的值,如果没有指定,则property必须不等于false
    String havingValue() default "";
    // 当指定的property未被设置时,property的默认值
    boolean matchIfMissing() default false;
}

@AutoConfigureAfter

当前bean需要在@AutoConfigureAfter中指定的bean初始化完成后才能进行初始化。

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
@Documented
public @interface AutoConfigureAfter {
    // 应该已应用的自动配置类的名称
    Class<?>[] value() default {};
    // 应该已应用的自动配置类的名称
    String[] name() default {};
}

@AutoConfigureBefore

当前bean需要在@AutoConfigureBefore中指定的bean之前完成初始化,与@AutoConfigureAfter用法相同。

@AutoConfigureOrder

@Order注解的变种,用于指定AutoConfigure类之间的初始化次序,值越小,越优先被初始化。

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD })
@Documented
public @interface AutoConfigureOrder {
    int DEFAULT_ORDER = 0;
    // 顺序编号,默认为0
    int value() default DEFAULT_ORDER;

}

@ConditionalOnClass

当前classpath下存在指定类时,才会实例化当前Bean,与@AutoConfigureAfter用法相同。

@ConditionalOnMissingClass

当前classpath下不存在指定类时,才会实例化当前Bean,与@AutoConfigureAfter用法相同。

@ConditionalOnExpression

当SpEL表达式为true的时候,才会实例化当前Bean。

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnExpressionCondition.class)
public @interface ConditionalOnExpression {
    // 指定的SpEL表达式
    String value() default "true";
}
上一篇 下一篇

猜你喜欢

热点阅读