Spring框架中条件注解@Conditional的用法和示例

本文深入探讨Spring框架中@Conditional注解的使用方法与原理,包括@ConditionalOnWebApplication等衍生注解,以及Condition接口的实现,揭示了SpringBoot自动装配的条件判断机制。
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自动装配过程中,各个组件模块在不同应用 场景下的实例加载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姠惢荇者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值