概述
@Conditional注解是Spring4之后提供的一个注解,该注解可以作用在类和方法上。
这个注解用于添加条件来控制Bean是否可以注册到Spring的IOC容器中。
从@Conditional注解的源码中,我们可以发现该注解的value属性接收的值是一个Condition类型的数组。Condition接口就是控制Bean注入的条件。
Condition接口中提供了一个matches方法,该方法用于编写业务逻辑控制bean的注入,当方法的返回值为true时,表示标注了该注解的Bean可以注入到Spring的IOC容器中,为false时表示不可以。
matches方法有两个参数:ConditionContext和AnnotatedTypeMetadata。
ConditionContext是:判断条件的上下文信息。(重点关注这个参数)
AnnotatedTypeMetadata:注解所在位置的注释信息。
案例演示
通过代码来演示一下@Conditional注解的使用。
需要注入的bean
// 汽车
public class Car {
public Car() {
System.out.println("Car的无参构造执行了!");
}
}
// 火车
public class Train {
public Train() {
System.out.println("Train的无参构造执行了!");
}
}
自定义条件类
// 用于演示,不做任何逻辑处理返回true
public class YesCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 获取到IOC使用的BeanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 获取到类加载器
ClassLoader classLoader = context.getClassLoader();
// 获取到当前IOC容器运行的环境所对应的一些信息
Environment environment = context.getEnvironment();
// 获取到bean定义的注册类
BeanDefinitionRegistry registry = context.getRegistry();
return true;
}
}
// 用于演示,不做任何逻辑处理返回false
public class NoCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return false;
}
}
配置类
@Configuration
public class BeanLoadingConfig {
@Bean
@Conditional({YesCondition.class})
public Car car() {
return new Car();
}
@Bean
@Conditional({NoCondition.class})
public Train train() {
return new Train();
}
}
测试类
public class TestBeanLoading {
@Test
public void test1() {
// 创建Spring的IOC容器
ApplicationContext context = new AnnotationConfigApplicationContext(BeanLoadingConfig.class);
}
}
执行结果
我试验了多种情况总结出了以下几点结论:
1、当@Conditional注解中有多个判断条件时,必须所有条件都满足(都返回true),该bean才会注入到IOC容器中。
2、如果@Conditional注解添加到了配置类上,那么当条件不满足时,类中配置的多个bean都不会注册到IOC容器中。
3、当@Conditional注解在类和方法上都存在时,会先验证类上的条件,然后在验证方法上的条件,这其中有一项不满足将不会把bean注册到IOC容器中。
今天的分享就到这里了,如果感觉“菜鸟”写的文章还不错,记得点赞、转发加关注呦!你们的支持就是我坚持下去的动力。文章哪里写的有问题的也希望大家可以指出,我会虚心受教。