SpringBoot中@Conditional注解的使用

 更新时间:2024年01月04日 08:34:16   作者:Splaying  
这篇文章主要介绍了SpringBoot中@Conditional注解的使用,@Conditional注解是一个条件装配注解,主要用于限制@Bean注解在什么时候才生效,以指定的条件形式控制bean的创建,需要的朋友可以参考下

1、基本介绍

  • @Conditional注解是一个条件装配注解,主要用于限制@Bean注解在什么时候才生效。以指定的条件形式控制bean的创建
  • @Conditional可以自定义条件进行装配或者不装配…
  • @Conditional本身还是一个父注解,派生出大量的子注解;可以按需加载
  • 因此在学习SpringBoot的时候是非常有必要学习这个注解的使用的,SpringBoot就是按需加载。
  • Conditional注解和所有子注解首先必须依托@Configuration配置类注解
  • 都可以加载类或者方法上;加载类上的含义所有的方法都按照这个条件装配、加载方法上只有该方法进行条件装配。
  • 注:Conditional注解是Spring4.0就有的,旗下的子注解是SpringBoot1.0有的。

2、@Conditional注解

使用Conditional注解进行条件装配时需要自定义类实现Condition接口(spring包下的,不是JUC包下)

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
	// 自定义类实现Condition接口,完成给出指定的条件。
	Class<? extends Condition>[] value();
}

2.1、自定义条件

如果存在dog1则不会对条件装配bean进行创建。

public class MyCondition implements Condition {
    /**
     * @param context: 判断条件使用的上下文环境
     * @param metadata: 扫描的注解信息
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 1. 获取bean工厂
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        // 2. 获取运行环境, 可以根据操作系统的环境进行限制bean
        Environment environment = context.getEnvironment();
        // 3. 获取BeanDefinition注册定义表
        context.getRegistry();
        // 4. 获取资源加载器
        context.getResourceLoader();
        // 5. 获取类加载器
        ClassLoader classLoader = context.getClassLoader();
        if (beanFactory.containsBean("dog1")) {
            return false;
        }
        /**
         *      可以根据以上条件进行条件装配
         *      true: 装配
         *      false: 不装配
         */
        return true;
    }
}

2.2、条件装配测试

@Configuration
public class MyConfig {
    @Bean("user1")
    public User user1(){
        return new User("splay", 22, "男");
    }
    @Bean("dog1")
    //@ConditionalOnBean(name = {"dog2"})
    public Dog dog1(){
        return new Dog("金毛", 4,"公");
    }
    @Bean("dog2")
    @Conditional(value = MyCondition.class)
    public Dog dog2(){
        return new Dog("拉布拉多", 3,"母");
    }
}

在dog2上加上条件装配,当扫描到这个bean时会进行条件判断。

在这里插入图片描述

3、@ConditionalOnBean子注解

子注解其实也是Conditional注解的特定装配,只不过条件类已经实现好了。

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class)			//OnBeanCondition是一个Condition接口的实现类
public @interface ConditionalOnBean {

	// 1. 按照bean的类型进行检查
	Class<?>[] value() default {};

	// 2. 按照bean的类型进行检查
	String[] type() default {};

	// 3. 按照bean的注解进行检查
	Class<? extends Annotation>[] annotation() default {};

	// 4. 按照BeanName进行检查
	String[] name() default {};

	// 5. 搜索策略
	SearchStrategy search() default SearchStrategy.ALL;

	// 6. 不详
	Class<?>[] parameterizedContainer() default {};
}

3.1、条件装配测试(一)

当容器中存在dog1的时候在创建dog2,否则就不会进行创建。

@Configuration
public class MyConfig {

    @Bean("user1")
    public User user1(){
        return new User("splay", 22, "男");
    }


    @Bean("dog1")
    public Dog dog1(){
        return new Dog("金毛", 4,"公");
    }

    @Bean("dog2")
    @ConditionalOnBean(name = {"dog1"})
    public Dog dog2(){
        return new Dog("拉布拉多", 3,"母");
    }
}

在这里插入图片描述

3.2、条件装配测试(二)

在使用时发现条件装配与bean的编写注册顺序有关系,如果先后顺序导致将会出现失败的情况。

@Configuration
public class MyConfig {

    @Bean("user1")
    public User user1(){
        return new User("splay", 22, "男");
    }


    @Bean("dog1")
    @ConditionalOnBean(name = {"dog2"})		//当有dog2组件的时候创建dog1
    public Dog dog1(){
        return new Dog("金毛", 4,"公");
    }

    @Bean("dog2")
    public Dog dog2(){
        return new Dog("拉布拉多", 3,"母");
    }
}

在这里插入图片描述

对比上面测试一发现dog1并没有成功创建,猜测创建的时候估计是按照某种顺序进行的!

因此在使用条件装配进行创建的时候一定要注意呗依赖的条件是否要先创建的问题!

到此这篇关于SpringBoot 中@Conditional注解的使用的文章就介绍到这了,更多相关@Conditional注解使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture

    Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture

    这篇文章主要介绍了Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture,本文直接给出实现代码,代码中包含详细注释,需要的朋友可以参考下
    2015-06-06
  • Java使用MulticastSocket实现群聊应用程序

    Java使用MulticastSocket实现群聊应用程序

    这篇文章主要为大家详细介绍了Java使用MulticastSocket实现群聊应用程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Java设计模式之原型设计示例详解

    Java设计模式之原型设计示例详解

    这篇文章主要为大家详细介绍了Java的原型设计模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • SpringBoot实现接口防刷的两种方法

    SpringBoot实现接口防刷的两种方法

    接口被刷指的是同一接口被频繁调用,可能是由于以下原因导致:恶意攻击和误操作或程序错误,本文给大家介绍了SpringBoot实现接口防刷的两种方法,并有相关的代码示例供大家参考,需要的朋友可以参考下
    2024-06-06
  • 利用maven-shade-plugin插件解决不兼容的依赖冲突的情况

    利用maven-shade-plugin插件解决不兼容的依赖冲突的情况

    本文介绍了在Maven工程中遇到底层依赖包版本冲突问题,使用maven-shade-plugin插件解决冲突的方法,并详细描述了步骤及注意事项
    2026-05-05
  • RabbitMQ的安装和配置可视化界面的详细步骤

    RabbitMQ的安装和配置可视化界面的详细步骤

    这篇文章主要介绍了RabbitMQ的安装和配置可视化界面的详细步骤,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • Mybatis中collection和association的使用区别详解

    Mybatis中collection和association的使用区别详解

    这篇文章主要介绍了Mybatis中collection和association的使用区别详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • Java高并发之CyclicBarrier的用法详解

    Java高并发之CyclicBarrier的用法详解

    CyclicBarrier 是 Java 中的一种同步工具,它可以让多个线程在一个屏障点处等待,直到所有线程都到达该点后,才能继续执行。本文就来和大家聊聊它的用法,需要的可以参考一下
    2023-03-03
  • 详解Java的readBytes是怎么实现的

    详解Java的readBytes是怎么实现的

    众所周知,Java是一门跨平台语言,针对不同的操作系统有不同的实现,下面小编就来从一个非常简单的api调用带大家来看看Java具体是怎么做的吧
    2023-07-07
  • Java SE使用数组实现高速数字转换功能

    Java SE使用数组实现高速数字转换功能

    随着大数据时代的到来,数字转换功能变得越来越重要,在Java开发中,数字转换功能也是经常用到的,下面我们就来学习一下如何使用Java SE数组实现高速的数字转换功能吧
    2023-11-11

最新评论