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注解使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springboot实现热部署操作方法

    springboot实现热部署操作方法

    这篇文章主要介绍了springboot实现热部署操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • Java SpringBoot自定义starter详解

    Java SpringBoot自定义starter详解

    大家好,本篇文章主要讲的是Java SpringBoot自定义starter详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次
    2022-01-01
  • Java实现单链表SingleLinkedList增删改查及反转 逆序等

    Java实现单链表SingleLinkedList增删改查及反转 逆序等

    单链表是链表的其中一种基本结构。一个最简单的结点结构如图所示,它是构成单链表的基本结点结构。在结点中数据域用来存储数据元素,指针域用于指向下一个具有相同结构的结点。 因为只有一个指针结点,称为单链表
    2021-10-10
  • 解决spring结合mybatis时一级缓存失效的问题

    解决spring结合mybatis时一级缓存失效的问题

    这篇文章主要介绍了解决spring结合mybatis时一级缓存失效的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • Spring Boot实现文件上传下载

    Spring Boot实现文件上传下载

    这篇文章主要为大家详细介绍了Spring Boot实现文件上传下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • idea配置检查XML中SQL语法及书写sql语句智能提示的方法

    idea配置检查XML中SQL语法及书写sql语句智能提示的方法

    idea连接了数据库,也可以执行SQL查到数据,但是无法识别sql语句中的表导致没有提示,下面这篇文章主要给大家介绍了关于idea配置检查XML中SQL语法及书写sql语句智能提示的相关资料,需要的朋友可以参考下
    2023-03-03
  • Java实现监听UDP协议的指定端口并收到数据按照十六进制输出方式

    Java实现监听UDP协议的指定端口并收到数据按照十六进制输出方式

    这篇文章主要介绍了Java实现监听UDP协议的指定端口并收到数据按照十六进制输出方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • Java实现斗地主与猜数字游戏详细流程

    Java实现斗地主与猜数字游戏详细流程

    这篇文章主要介绍了怎么用Java来写斗地主种洗牌和发牌的功能,以及猜数字的游戏,斗地主相信大家都知道,同时也知道每一局都要洗牌打乱顺序再发牌,本篇我们就来实现它们能,感兴趣的朋友跟随文章往下看看吧
    2022-04-04
  • 浅谈一下Java中枚举的用法

    浅谈一下Java中枚举的用法

    这篇文章主要介绍了浅谈一下Java中枚举的用法,枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数,当一个变量有几种固定可能的取值时,就可以将它定义为枚举类型,需要的朋友可以参考下
    2023-04-04
  • Spring JDBC使用步骤和事务管理

    Spring JDBC使用步骤和事务管理

    Spring JDBC是Spring框架用来处理关系型数据库的模块,对JDBC的API进行了封装,这篇文章主要介绍了Spring JDBC使用步骤和事务管理,需要的朋友可以参考下
    2023-12-12

最新评论