天天看点

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}这样的结果