spring-Condition条件化配置

来源:互联网 发布:python class 自己 编辑:程序博客网 时间:2024/06/05 19:26

spring4.0引入的新特性,当你注册bean时,可以对这个bean添加一定的自定义条件,当满足这个条件时,注册这个bean,否则不注册。


条件化最重要的是Condition接口,如下定义。

public interface Condition {    boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);}

实现这个接口,重写matches方法,返回true则意味着注册被注解的bean,false则跳过被注解的bean。


举个栗子:我们的系统中,如果注册了Cat类,就不要注册Dog类了。

public class Person {    private String name;    @Autowired    private  Animal animal;    public Animal getAnimal() {        return animal;    }    public void setAnimal(Animal animal) {        this.animal = animal;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}


public class Animal {    private String name;    public String getName() {        return getClass().getName();    }    public void setName(String name) {        this.name = name;    }}

public class Cat extends Animal{}

public class Dog extends Animal{}


配置类

@Configurationpublic class BeanConfig {    @Bean    public Person person(){        return new Person();    }    @Bean    public Cat cat(){        return new Cat();    }    @Bean    //创建这个bean的必要条件,matches方法必须为true才会注册bean,反之忽略bean。    //扫描到bean立刻调用,不会等配置类中的所有bean都注册好之后再调用,因此Cat bean写前面,写后面会出错。    @Conditional({PetCondition.class})    public Dog dog(){        return new Dog();    }}


自定义条件

public class PetCondition implements Condition {    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {        //输出 org.springframework.core.type.StandardMethodMetadata        System.out.println(annotatedTypeMetadata.getClass().getName());        //强转        StandardMethodMetadata standardMethodMetadata = (StandardMethodMetadata)annotatedTypeMetadata;        //AppConfig下的dog方法调用,输出dog        System.out.println(standardMethodMetadata.getMethodName());        //如果person        return conditionContext.getRegistry().containsBeanDefinition("person") && !conditionContext.getRegistry().containsBeanDefinition("cat");        //conditionContext.getRegistry()获取注册的bean        //conditionContext.getBeanFactory()获取提供bean definition的解析,注册功能,再对单例来个预加载(解决循环依赖问题).        //conditionContext.getEnvironment()获取环境配置        //conditionContext.getResourceLoader()ResourceLoader所加载的资源        //conditionContext.getClassLoader()获取类加载器//        annotatedTypeMetadata.        //annotatedTypeMetadata 被加上注解的源数据信息。比如annotatedTypeMetadata.    }}



测试代码

ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);        Person person = (Person)context.getBean("person");        System.out.println(person.getAnimal().getName());


输出:

org.springframework.core.type.StandardMethodMetadata
dog
com.demo.entity.Cat


按照上一节的知识来看,明明配置类中注册了Animal的两种实现类,并且我们没有缩小bean的定义,然而并没有报错。这是因为在注册Dog的时候我们做了条件化判断,发现已经注册了Cat,因此跳过了Dog的注册,所以整个系统中Animal的子类只有Cat,Person类成功注入Cat。