spring4.0引入的新特性,当你注册bean时,可以对这个bean添加一定的自定义条件,当满足这个条件时,注册这个bean,否则不注册。
Condition源码:
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
实现接口,重写matches方法,返回true则注册被注解的bean,false则跳过被注解的bean。
举个栗子:我们的系统中,如果注册了Cat类,就不要注册Dog类了。
例子来源:https://blog.csdn.net/helianus/article/details/78753452
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{
}
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;
}
}
@Configuration
public 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();
}
}
上面为配置类,此配置类的dog方法添加了conditional注解,即注册dog类的这个bean的条件是PetCondition.class定义的条件
PetCondition类:
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。
如项目有使用Condition条件的地方,可以直接参考这个例子使用。