天天看點

spring注解 Conditional注解

        @Conditional注解,官方解釋為:“隻有當所有指定的條件都滿足是,元件才可以注冊”,主要的用處是在建立bean時增加一系列限制條件,在條件通過時,才可以成功建立bean。

        Conditional的聲明如下:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    Class<? extends Condition>[] value();
}
           

        接收的參數是一個數組,數組元素是Condition類型,Condition是一個接口:

public interface Condition{
/** Determine if the condition matches.
* @param context the condition context
* @param metadata meta-data of the {@link AnnotationMetadata class} or
* {@link Method method} being checked.
* @return {@code true} if the condition matches and the component can be registered
* or {@code false} to veto registration.
*/
boolean matches(ConditionContext context, AnnotatedTypeMedata metadata);
}
           

        當要自定義元件注冊規則時,編寫一個Condition的實作類即可,在實作類中定義通過的規則:

public class MyCondition1 implements Condition {
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {

        //IOC使用的beanFactory
        ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
        //類加載器
        ClassLoader classLoader = conditionContext.getClassLoader();
        //目前運作環境
        Environment environment = conditionContext.getEnvironment();
        //bean定義的注冊類
        BeanDefinitionRegistry registry = conditionContext.getRegistry();
        //資源加載器
        ResourceLoader resourceLoader = conditionContext.getResourceLoader();
        if(registry.containsBeanDefinition("person")){
            return true;
        }

        return false;
    }
}
           

        上述代碼是我編寫的一個Condition的實作類,規則是當容器中存在一個名為person的bean時,條件生效。可以通過conditionContext來擷取更多的資訊,用于自定義條件。

        另外,我還定義了一個Condition的實作類,判斷條件則和第一個的相反,在配置類中應用上@Condition

//配置類
@Configuration
public class MyConfig3 {


    //@Lazy
    @Bean("person")
    public Person person(){
        Person person =  new Person("張三",20);
        System.out.println(person);
        return person;
    }

    @Conditional({MyCondition1.class})
    @Bean
    public Person p1(){
        Person person =  new Person("李四",21);
        System.out.println(person);
        return person;
    }

    @Conditional({MyCondition2.class})
    @Bean
    public Person p2(){
        Person person =  new Person("王五",22);
        System.out.println(person);
        return person;
    }
}

//測試類
public class AnnotationTest {

    @Test
    public void testCondition(){
        ApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig3.class);
    }
}
           

輸出結果:

spring注解 Conditional注解

        配置類的代碼中,我将@Lazy注解給注釋掉了,如果放開該注釋,那麼,輸出就隻會是Person{name='王五',22},因為容器在建立時,因懶加載的緣故,person這個bean并沒有被加載到容器當中,是以,另外一個條件生效,輸出Person{name='王五',22}這樣的結果