@Conditional四个较常用的派生注解总结

news2024/12/27 18:10:20

该内容是在学习SpringBoot底层的时候,看到SpringBoot的使用,所以这的做一个简单的总结方便以后复习。可能会有一些问题,还望指出共同学习

@Conditional注解:

  • 作用:按照一定的条件进行判断,在满足给定条件后才会注册对应的bean对象到Spring的IOC容器中。
  • 位置:方法、类
  • @Conditional本身是一个父注解,派生出大量的子注解:
    • @ConditionalOnClass:注解用于基于类路径(Classpath)的条件装配
    • @ConditionalOnBean 注解会检查 IOC 容器中是否存在一个或多个指定的 Bean,只有在满足条件的情况下才会进行后续的自动配置
    • @ConditionalOnMissingBean:判断ioc中没有对应的bean(类型或名称),才注册bean到IOC容器。
    • @ConditionalOnProperty:判断配置文件中有对应属性和值,才注册bean到IOC容器。

下面就对@Conditional注解较常用的派生注解来做一个解释:

解释之前先对测试的结构做一个了解:

  1. 包结构

  1. 每个类的代码

    • pojo包
    /**
     * Parent类
     */
    public class Parent {
    }
    
    //
    /**
     * Child类
     */
    public class Child {
    }
    /
    /**
     * 其他类
     */
    public class Others {
    }
    
    • 配置类
    /**
     * 配置文件,对Bean的处理
     */
    @Configuration
    public class BeanConfig {
        
        @Bean
        public Child getChild(){
            return new Child();
        }
    }
    

@ConditionalOnClass

@ConditionalOnClass 注解用于基于类路径(Classpath)的条件装配,即根据某个类是否存在于 classpath 中进行条件判断,从而控制 Spring Boot 应用中 Bean(组件)是否需要被创建。

具体来说,@ConditionalOnClass 注解会检查指定类路径中的指定的类是否存在,如果该类在 Classpath 中,则会将当前的Bean放入到IOC容器中。反之,如果指定类没有存在于 Classpath 则不会 创建当前的Bean
常用的属性有:

  • name:需要是全路径类名,多个类名称使用逗号分隔。当有多个类名称,那么必须所有的类都存在时才会创建当前的Bean。

  • value : 会判断Classpath中是否有指定的字节码文件,如果有多个只有当都满足的情况才会创建当前Bean

        @Bean
        @ConditionalOnClass(name = {"com.yfs1024.pojo.Parent","com.yfs1024.pojo.Others"})
        public Child getChild(){
            return new Child();
        }
    

    当两个都存在时Spring会将当前@Bean注解修饰的方法的返回放入IOC容器,名字为方法名(下面就不在赘述)

    • 通过可视化界面可以看到,高亮部分是Spring默认生成,没有高亮是我们自己写的类

在这里插入图片描述

在这里插入图片描述

如果其中一个类不存在就不创建如图 2;

对于通过类型判断(注解中的value可以省略),也是如此,判断的是在编译之后有没有对应的字节码文件,代码如下:

    @Bean
    @ConditionalOnClass({Parent.class, Others.class})
    public Child getChild(){
        return new Child();
    }

此时编译之后的Classpath文件存在这两个文件的字节码文件,所以会将这个Bean放入到容器中。结果如图1;

@ConditionalOnBean

@ConditionalOnBean 它的作用是根据 Bean 的条件来控制某些 Bean 的加载和初始化。它可以被用于方法上面,表示只有在指定类型的 Bean 存在时才会进行方法的调用。也可以用于类上面,表示只有在指定类型的 Bean 存在时,该类才会被加载和初始化。

这个注解的参数常用的应该也是那两个 name:value : 当然还有type,annotation, 这里就不再介绍,等我用到了再补充

//	Class<?>[] value() default {};   当参数为value是传入的需要是字节码文件,即Class类的对象
/
	@Bean
    @ConditionalOnBean({Parent.class, Others.class})
    public Child getChild(){
        return new Child();
    }

此时因为IOC容器中并没有这个字节码类对象的两个对象,容器中的图如图2所示;

现在我们在Parent和Others上添加@Component注解让Spring扫描到,此时,容器中就有了这两个对象,如下,所以当前的方法的返回值就会放入到容器中。结果如图1所示:修改Parent和Others代码如下:

在这里插入图片描述

@Component
public class Others {
}
//
@Component
public class Parent {
}

另外也可以通过名称来限定是否创建,但是在此时可能就出现容器中并没有加入当前对象,即容器中没有getChild这个对象,但是有Others和Parent这两个对象的现象。此时我们就可以通过自己指定,来确定顺序。

原因: 这是因为在判断的时候其他的两个对象还没有创建

@Bean
@ConditionalOnBean(name = "getParent")
public Child getChild(){
    return new Child();
}

此时我们就可以通过自己指定,来确定顺序。

@Bean
public Parent getParent(){
    return new Parent();
}

@Bean
@ConditionalOnBean(name = "getParent")
public Child getChild(){
    return new Child();
}

此时再看就有了。解决。所以在这里也推荐使用value参数,较好。

@ConditionalOnMissingBean

当IOC容器 中不存在指定类型的Bean时,才会加载该Bean,否则将会忽略这个Bean。

常见的使用场景是:当某个类不存在时才创建对应的 Bean。

    @Bean
    public Parent getParent(){
        return new Parent();
    }


    @Bean
    @ConditionalOnMissingBean(name = "getPar2ent")
    public Child getChild(){
        return new Child();
    }

此时会创建因为容器中没有getPar2ent这个对象,如下,但是当为getParent,时就不会创建。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pKb9Th0b-1681145080120)(C:\Users\57589\AppData\Roaming\Typora\typora-user-images\image-20230410234600588.png)]

这个比较好理解,结果略过

@ConditionalOnProperty

@ConditionalOnProperty主要作用是根据应用程序的配置属性来决定是否创建 Bean.

常见的使用场景是:根据配置来控制某些 Bean 是否启用或者禁用,从而实现应用程序的灵活性和可配置性。
@ConditionalOnProperty 注解可以根据一或多个配置属性的值来决定是否创建 Bean,配置属性的值可以是 true、false、null、或者一个具体的字符串。
例如,我们需要根据某个配置属性来判断是否创建一个 Bean,可以这样写:

application.properties配置文件中

aliyun:
  oss:
    endpoint: hangzhou.aliyuncs
@Bean
@ConditionalOnProperty("aliyun.oss.endpoint")
public Others getOthers(){
    return new Others();
}

即当配置文件中有aliyun.oss.endpoint 这个配置的时候才创建当前的对象。结果如图

看到这里其实我们也就可以想到,为什么Mybatis在没有yml配置文件中配置时会报错,我猜就是这个原因

对于这个注解其中的几个参数就要学习一下了

  1. havingValue:指定配置属性的值与该属性值匹配时,创建 Bean,默认为 “”。
  2. matchIfMissing:指定当配置属性不存在时,是否创建 Bean,默认是 true。
  3. prefix:用于设置配置属性的前缀。
  4. name:用于指定配置属性的名称。
  5. value:用于指定配置属性的名称,与 name 属性类似。
  • havingValue
@Bean
@ConditionalOnProperty(value = "aliyun.oss.endpoint" , havingValue = "hangzhou.aliyuncs")
public Others getOthers(){
    return new Others();
}

此时因为我们指定的值和配置文件中的值相同,在此时就会创建当前的Bean

在这里插入图片描述

但是如果把后面的havingValue修改的和配置文件中不一致时,此时就不会创建Bean,比如修改为havingValue = "yfs1024"

  • boolean matchIfMissing() default false;

Spring给的解释:
Specify if the condition should match if the property is not set. Defaults to false.
Returns:
if the condition should match if the property is missing

翻译:指定如果未设置属性,则条件是否应匹配。默认为 false。返回:如果缺少属性,条件是否匹配

比如说我们把代码修改一下,把matchIfMissing设置为true,此时表示,即使配置文件没有这个配置依然创建Bean

注意:此时因为是多个参数,所以现在value就不可以省略了。

@Bean
@ConditionalOnProperty(value = "aliyun.oss.XXXX" , matchIfMissing=true)
public Others getOthers(){
    return new Others(); 	
}
  • String prefix( ) default “”;

在这里插入图片描述

在上述示例中,我们使用了 “aliyun.oss” 作为配置属性的前缀。 application.yml配置如下:

aliyun:
	oss: 
		enabled: true

那么就会创建一个 Others Bean。如果把 aliyun.oss.enabled 改成 false,或者删除该属性,Others 就不会被创建出来。
总之,@ConditionalOnProperty 注解的 prefix 属性可以指定配置属性的前缀,从而更好地管理和控制应用程序的配置属性。


先总结到这吧,睡觉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/426187.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如果采用密钥对的形式登录系统后,如何由普通用户切换到root用户

使用xshell工具 采用秘钥的方式进行登录 创建一个新用户并设置密码 切换到新用户之后 su root 想要切换成root用户的时候 输入密码提示 su:Authentication failure su&#xff1a;身份验证失败 使用秘钥之后是不能使用密码再进行登录 我去阿里云查了一下 有一个相同…

stable diffusion 安装xFormers 报错:Couldn‘t install open_clip.

一、No module ‘xformers’. Proceeding without it. 这是因为没有安装xformers导致的。 解决办法&#xff1a; 在webui-user.bat文件这添加一行&#xff1a; set COMMANDLINE_ARGS--xformers如下图所示&#xff1a; 试着点击webui-user.bat&#xff0c;看能否下载&#xff…

17:00面试,17:04就出来了 ,问的实在是太...

从外包出来&#xff0c;没想到算法死在另一家厂子 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到8月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个兄弟内推…

你具备抽离与封装的思想吗?

笔者最近思考了自己参与的分布式系统业务的架构小细节&#xff0c;虽然笔者每天做的是实现部分需求与业务&#xff0c;但是笔者还是拥有很多时间去读底层源码的&#xff0c;加之笔者自身的思考与实践demo的总结&#xff0c;笔者将在本篇文章中提出笔者自己对“抽离”与“封装”…

Nginx编译安装及配置文件详解

写在前面 Centos版本&#xff1a;Centos 7.6 - 64bit Nginx版本&#xff1a;1.20.2 一、什么是Nginx Nginx (engine x) 是一款轻量级的Web 服务器 、反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器。 二、Nginx用在哪些地方 2.1 静态资源服务 动静…

mkv视频文件怎么转成mp4,这3个方法很好用

对于那些电脑不是很精通的小伙伴来说&#xff0c; mkv视频文件怎么转成mp4&#xff1f;小编先来介绍一下mkv视频格式&#xff0c;mkv是一种开放标准的自由的容器和文件格式&#xff0c;是一种多媒体封装格式&#xff0c;能够在一个文件中容纳无限数量的视频、音频、图片或字幕轨…

MVCC底层原理

目录说明MVCC的底层原理隐藏字段undo logRead View说明 在被面试官问面试题的时候&#xff0c;首先它问了Mysql的事务的隔离级别有几种&#xff1f;默认是哪种&#xff1f;他们分别解决了什么问题&#xff1f; 我在一顿回答“巴巴巴巴。。。。”之后&#xff0c;它又继续问题…

追踪项目进展常用的衡量方法

作为项目管理活动&#xff0c;项目中的进度跟踪可以帮助你了解项目实时的完成状态。有了正确的方法、项目管理工具和指标&#xff0c;项目跟踪可以指导你的团队的行动&#xff0c;甚至在问题出现之前向你发出预警。 项目经理使用各种方法、工具和指标来跟踪进度。其中最常见的…

自然语言处理(Natural Language Processing,NLP)简要

自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;简要一、发展状况二、发展优势三、发展瓶颈四、具体研究方向五、自然语言处理工具六、未来发展方向自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;是计算机…

(原创)Flutter基础入门:各种常用容器类组件

前言 上篇博客主要讲了Flutter的Shape实现 Flutter基础入门&#xff1a;实现各种Shape效果 今天主要讲下Flutter中常用的一些容器组件 Flutter中组件数量很多&#xff0c;分类方式也各有不同 比如可以分为有态组价和无态组件 又可以分为容器组件、功能组件等 拿功能组件来说 有…

docker网络详解,自定义docker网络

文章目录一、初识docker网络1、docker0虚拟网桥2、docker网络常用基本命令3、docker网络可以解决的问题二、docker网络模式1、四种网络模式2、容器实例内默认网络IP生产规则3、bridge模式4、host模式5、none模式6、container模式五、自定义网络模式1、过时的docker link2、使用…

【英语】大学英语CET考试,词汇语法导学方法论笔记(50h+)

文章目录1、谭剑波-词汇直播课1-2&#xff08;词汇学习3个关键&#xff09;1.1 看不懂句子的原因&#xff08;词汇的重要性&#xff09;1.2 记不住单词的原因&#xff08;死记硬背70%&#xff09;1.3 理解单词的本质&#xff08;词根词缀&#xff0c;26字母&#xff0c;联想辅助…

D3D11和D3D12共享资源

最近碰到个伪需求: 游戏串流。 游戏引擎用D3D12渲染&#xff0c; 再把游戏画面做视频编码&#xff0c; 通过网络发送到远端做解码显示。 第一反应就是走全GPU的流程&#xff0c; 不要用CPU把显存里的数据拷来拷去。 所以先获取渲染完的D3D12的frame buffer&#xff0c; 然后送给…

进程管理 - 银行家算法

文章目录1 概述2 银行家算法2.1 原理2.2 例题1 概述 #mermaid-svg-7QKAqjQpckpStO9Q {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-7QKAqjQpckpStO9Q .error-icon{fill:#552222;}#mermaid-svg-7QKAqjQpckpStO9Q .e…

android framework-PackageManagerService(PKMS)包管理服务

一、概述 Android系统启动过程中&#xff0c;会启动一个包管理服务PackageManagerService(PKMS)&#xff0c;这个服务主要负责扫描系统中指定目录&#xff0c;找出里面以apk结尾的文件&#xff0c;通过对这些文件进行解析&#xff0c;得到应用程序的所有信息并完成应用程序的安…

算法学习day59

算法学习day591.力扣503.下一个更大元素II1.1 题目描述1.2 分析1.3代码2.力扣42. 接雨水2.1 题目描述2.2 分析2.3 代码3.参考资料1.力扣503.下一个更大元素II 1.1 题目描述 题目描述&#xff1a; 给定一个循环数组&#xff08;最后一个元素的下一个元素是数组的第一个元素&a…

【大数据Hadoop】HDFS3.3.1-Namenode-租约管理

租约管理前言LeaseManager.LeaseLeaseManager添加租约 - addLease租约检查 - FsNamesystem.checkLease租约更新 - renewLease删除租约 - removeLease租约检查 - Monitor 线程租约恢复 - Monitor 线程发起租约恢复 - 其他方式发起前言 我们知道 HDFS 文件是 write-once-read-man…

CloudCompare插件开发之点云如何创建、保存并显示?

文章目录0.引言1.创建插件工程2.代码编写3.显示点云4.保存点云0.引言 CloudCompaer是一款优秀的开源软件&#xff0c;在点云处理时可以根据实际要求开发合适的插件&#xff0c;在实际使用中&#xff0c;创建点云、保存点云、显示点云的操作较为基础&#xff0c;为了使这些操作得…

施工组织设计合集

34-6 施工组织设计02017-年亲曼旗大镇市政道路及广场公园园林绿化工程(第一.A1-1五中教学楼施工组织设计A2施工组织设计(方案) 报审表hasuploaded-中建施|组织设计 (22P)安徽大包庄125万吨疏铁矿斜坡道施工组织设计 (修改)宝山万科四季花城施T组织设计 (126P)对税信息培训中心装…

软件测试,月薪还没过万的进来看

目录 前言 一、技能提升 二、多语言掌握 三、团队协作 四、持续学习 五、提高测试效率 六、质量保障 七、职业发展 八、总结 前言 在当今IT行业中&#xff0c;软件测试是一个不可或缺的环节。随着互联网和移动应用的发展&#xff0c;对软件质量的要求也越来越高。因此…