1、@Conditional用法示例
@Conditional注解是用来判断是否满足指定的条件来决定是否进行Bean的实例化及装配,下面通过示例演示@ConditionalOnMissingClass、@ConditionalOnMissingBean、@ConditionalOnClass和@ConditionalOnBean的用法。
1、定义基础类,根据这些类或实例判断指定的类是否被加载
@Component
public class BeanOne {
public void run(){
System.out.println("BeanOne.run()方法。");
}
}
@Component
public class BeanTwo {
public void run(){
System.out.println("BeanTwo.run()方法。");
}
}
public class BeanThree {
public void run(){
System.out.println("BeanThree.run()方法。");
}
}
这三个类,前两个通过@Component注解,会被加载到Spring IOC容器中,第三个类没有被注解,所以在Spring IOC容器中不存在该类的实例。
2、配置测试类
注解@ConditionalOnBean:
主要使用了注解@ConditionalOnBean,主要是根据Spring IOC容器中是否有该类的实例对象来进行判断。根据前面的配置,可以知道BeanOne、BeanTwo两个类的实例会被加载到Spring IOC容器中,而BeanThree类的实例不会被加载到容器中,所以第一种情况下,该类不会被加载,第二种情况该类会被加载。
@Configuration
//第一种情况:不会被加载,BeanThree不在IOC容器中
@ConditionalOnBean({
BeanOne.class, BeanThree.class})
//第二种情况:会被加载,都在容器内
//@ConditionalOnBean({BeanOne.class, BeanTwo.class})
public class TestOnBean {
}
注解@ConditionalOnClass:
主要使用了注解@ConditionalOnClass,主要是根据类路径下是否有该类来进行判断。根据前面的配置,可以知道BeanOne、BeanThree两个类的都存在(BeanThree在类路径存在,但是不在Spring IOC容器中),而BeanFour类在类路径下不存在,所以第一种情况下,该类会被加载,第二种情况该类不会被加载。
@Configuration
//第一中情况:存在这两个类,所以会被加载
//@ConditionalOnClass({BeanOne.class, BeanThree.class})
//第二种情况:不会被加载,因为不存在BeanFour
@ConditionalOnClass(name={
"com.qriver.spring.conditional.bean.base.BeanOne", "com.qriver.spring.conditional.bean.base.BeanFour"})
public class TestOnClass {
}
注解@ConditionalOnMissingBean:
主要使用了注解@ConditionalOnMissingBean,主要是根据Spring IOC容器中是否有该类的实例对象来进行判断,和注解@ConditionalOnBean正好相反。根据前面的配置,可以知道BeanOne类的实例会被加载到Spring IOC容器中,而BeanThree类的实例不会被加载到容器中,所以第一种情况下,该类会被加载,第二种情况该类不会被加载。
@Configuration
//第一种情况:BeanThree不在IOC容器中,所以会被加载
//@ConditionalOnMissingBean(BeanThree.class)
//第二种情况:BeanOne在IOC容器中,所以不会被加载
@ConditionalOnMissingBean(BeanOne.class)
public class TestOnMissingBean {
}
注解@ConditionalOnMissingClass:
主要使用了注解@ConditionalOnMissingClass,主要是根据类路径下是否有该类来进行判断,正好跟注解@ConditionalOnClass相反。根据前面的配置,可以知道BeanOne、BeanThree两个类的都存在(BeanThree在类路径存在,但是不在Spring IOC容器中),而BeanFour类在类路径下不存在,所以第一种情况下,该类不会被加载,第二种情况该类会被加载。
@Configuration
//第一中情况:存在这两个类,所以会被加载
//@ConditionalOnClass({BeanOne.class, BeanThree.class})
//第二种情况:不会被加载,因为不存在BeanFour
@ConditionalOnClass(name={
"com.qriver.spring.conditional.bean.base.BeanFour"})
public class TestOnClass {
}
3、测试运行类
@Configuration
@ComponentScan("com.qriver.spring.conditional")
public class MainConfig {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
String[] beanNames = context.getBeanDefinitionNames();
for(int i=0;i<beanNames.length;i++){
System.out.println("bean名称:"+beanNames[i]);
}
}
}
运行上述代码,会根据注解条件,打印相应的被加载到Spring IOC容器中的类。这里不在展示打印结果了。
2、@Conditional注解
@Conditional注解是由Spring 4.0版本引入的新特性,可根据是否满足指定的条件来决定是否进行Bean的实例化及装配,比如,设定当类路径下包含某个jar包的时候才会对注解的类进行实例化操作。总之,就是根据一些特定条件来控制Bean实例化的行为。
@Conditional注解的源码如下:
@Target({
ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}
@Conditional注解及其衍生的注解结构如下图所示,其中大部分衍生的注解都是在在Spring Boot的autoconfigure项目中定义的,即在包org.springframework.boot.autoconfigure.condition下定义,大都是为了适应Spring Boot自动装配过程中,各个组件模块在不同应用 场景下的实例加载。

本文深入探讨Spring框架中@Conditional注解的使用方法与原理,包括@ConditionalOnWebApplication等衍生注解,以及Condition接口的实现,揭示了SpringBoot自动装配的条件判断机制。

1342

被折叠的 条评论
为什么被折叠?



