Spring的条件注解,一篇文章盘得清清楚楚明明白白

news2024/12/24 8:41:46

前言

在Spring中,条件注解可根据特定的条件来决定是否创建或配置Bean,这些条件可以基于类、属性、环境等因素。通过使用条件注解,我们可以在Spring容器中更加灵活地管理和控制组件的创建和注入,帮助我们更加灵活地管理和控制Bean的创建和注入,提高代码的灵活性和可维护性。总之,使用很简单,功能很强大。

如果你在项目里有类似下面这样的需求场景,选择使用相关的条件注解,绝对是是非常优雅的实现,没有之一。干货内容呀,如果怕以后找不到,马上收藏+关注吧。

  1. 自动化配置:根据特定的条件来决定是否创建或配置Bean,例如根据类路径下是否包含特定的库、特定的环境变量是否设置等条件来控制Bean的创建。
  2. 条件化装配:在Spring容器中,根据条件来决定是否加载某个Bean,例如根据当前所处的环境(如开发、测试、生产)来控制Bean的创建。
  3. Bean依赖:在Spring容器中,根据条件来决定是否创建依赖的Bean,例如只有当另外某个特定Bean也声明了之后才创建某个Bean。
  4. 自定义条件:通过实现Condition接口,自定义条件逻辑,根据特定条件来控制Bean的创建行为。

Springboot的相关条件注解大盘点

@ConditionalOnClass:当指定的class存在时,才会注入。

@ConditionalOnMissingClass:当指定的class不存在时,才会注入。

@ConditionalOnProperty:当指定的属性存在于application.properties文件中时,才会注入。

@ConditionalOnResource:当指定的资源文件存在时,才会注入。

@ConditionalOnWebApplication:用于判断当前应用是否为Web应用。

@ConditionalOnNotWebApplication:用于判断当前应用是否非Web应用。

@ConditionalOnBean:当Spring容器中存在指定的Bean时,才会注入。

@ConditionalOnMissingBean:当Spring容器中不存在指定的Bean时,才会注入。

@ConditionalOnSingleCandidate:当Spring容器中存在且仅存在一个指定的Bean时,才会注入。

@ConditionalOnExpression:当SpEL表达式为真时,才会注入。

@ConditionalOnJava:根据Java版本进行判断,不同版本有不同的处理方式。

Springboot的相关条件注解的功能描述与使用

@ConditionalOnClass

@ConditionalOnClass注解的作用是当项目中存在某个类时才会使标有该注解的类或方法生效。这个注解可以用来进行条件判断,以便在特定的类存在时才加载相应的Bean。例如,如果项目中引入了ApacheHttpClient包,那么可以使用@ConditionalOnClass(ApacheHttpClient.class)注解来标识这个Bean,只有当ApacheHttpClient类存在于类路径下时才会构建这个Bean。

在这个示例中,@ConditionalOnClass(ApacheHttpClient.class)注解表示只有当ApacheHttpClient类存在于类路径下时,才会加载HttpClientConfig类中的Bean。如果ApacheHttpClient类不存在,那么HttpClientConfig类中的Bean将不会被创建和注入。

@Configuration  
@ConditionalOnClass(ApacheHttpClient.class)  
public class HttpClientConfig {  
  
    @Bean  
    public ApacheHttpClient httpClient() {  
        return new ApacheHttpClient();  
    }  
}

@ConditionalOnMissingClass

@ConditionalOnMissingClass注解的作用是在类路径下不存在指定类时,才会使标有该注解的类或方法生效。这个注解可以用来进行条件判断,以便在特定的类不存在时才加载相应的Bean。例如,如果项目中没有引入MySQL数据库驱动包,那么可以使用@ConditionalOnMissingClass(MySQL.class)注解来标识这个Bean,只有当MySQL类不存在于类路径下时才会构建这个Bean。

@Configuration  
@ConditionalOnMissingClass("com.example.NonExistentClass")  
public class MyConfig {  
    // Bean definitions go here  
}

在这个示例中,@ConditionalOnMissingClass注解表示只有当"com.example.NonExistentClass"这个类不存在时,才会加载MyConfig类中的Bean。如果这个类存在,那么MyConfig类中的Bean将不会被创建和注入。

@ConditionalOnProperty

@ConditionalOnProperty注解的作用是根据指定的属性值来决定是否加载带有该注解的类或方法。如果属性存在且具有指定的值,那么带有@ConditionalOnProperty注解的类或方法将会被加载;否则,将不会加载。它通常用于在Spring应用程序中根据外部配置来决定哪些Bean需要创建和注入。

使用@ConditionalOnProperty注解时,可以通过指定属性名称和属性值来进行条件判断。其中,属性名称可以是应用程序配置文件(如application.properties)中的任意属性,而属性值则可以是任何字符串表达式。当配置文件中的属性值与指定的属性值相匹配时,带有@ConditionalOnProperty注解的类或方法将会被加载。

例如,假设在应用程序的配置文件中有一个名为myapp.database.url的属性,我们希望当该属性的值为jdbc:mysql://localhost:3306/mydb时才加载某个Bean。这时,我们可以在定义该Bean的类中使用@ConditionalOnProperty注解,并指定属性名称和属性值,如下所示:

@Configuration  
@ConditionalOnProperty(  
  name = "myapp.database.url",  
  havingValue = "jdbc:mysql://localhost:3306/mydb"  
)  
public class MyBeanConfig {  
  
    @Bean  
    public MyBean myBean() {  
        return new MyBean();  
    }  
}

在上面的示例中,当配置文件中的myapp.database.url属性值为jdbc:mysql://localhost:3306/mydb时,MyBeanConfig类中的Bean才会被创建和注入。否则,该Bean将不会被加载。

@ConditionalOnResource

@ConditionalOnResource注解的作用是当指定的资源文件存在时,才会使带有该注解的类或方法生效。它通常用于在Spring应用程序中根据资源文件的存在与否来决定哪些Bean需要创建和注入。

使用@ConditionalOnResource注解时,需要指定资源文件的路径和名称。当应用程序在启动时检测到该资源文件存在时,带有@ConditionalOnResource注解的类或方法将会被加载;否则,将不会加载。

例如,假设我们有一个名为config.properties的配置文件,其中包含了一些应用程序的配置信息。我们希望当该配置文件存在时才加载某个Bean。这时,我们可以在定义该Bean的类中使用@ConditionalOnResource注解,并指定配置文件的路径和名称,如下所示:

@Configuration  
@ConditionalOnResource(resources = "config.properties")  
public class MyBeanConfig {  
  
    @Bean  
    public MyBean myBean() {  
        return new MyBean();  
    }  
}

在上面的示例中,当应用程序在启动时检测到config.properties文件存在时,MyBeanConfig类中的Bean才会被创建和注入。否则,该Bean将不会被加载。

@ConditionalOnWebApplication

@ConditionalOnWebApplication注解用于判断当前SpringBoot应用是否为Web应用。根据应用类型,可以进一步确定是否满足某种特定的条件。

使用方式:

@Configuration  
@ConditionalOnWebApplication(type = Type.SERVLET)  
public class ForMatterAutoConfiguration {  
    // Bean definitions go here  
}

在上述示例中,@ConditionalOnWebApplication(type = Type.SERVLET)表示只有当SpringBoot应用类型为SERVLET应用类型时,ForMatterAutoConfiguration才会被加载到Spring容器。

该注解支持以下三种类型:

Type.ANY: 当应用是任何Web应用时,该注解修饰的配置类或方法都会生效。

Type.REACTIVE: 当应用是反应式Web应用(Spring WebFlux)时,该注解修饰的配置类或方法才会生效。

Type.SERVLET: 当应用是基于Servlet的Web应用(Spring MVC)时,该注解修饰的配置类或方法才会生效。

@ConditionalOnNotWebApplication

@ConditionalOnNotWebApplication注解用于判断当前SpringBoot应用是否非Web应用。当应用类型不是Web应用类型时,带有该注解的类或方法将会被加载;否则,将不会加载。

使用方式:

@Configuration  
@ConditionalOnNotWebApplication  
public class ForMatterAutoConfiguration {  
    // Bean definitions go here  
}

在上述示例中,只有当SpringBoot应用类型不是Web应用类型时,ForMatterAutoConfiguration才会被加载到Spring容器。

@ConditionalOnBean

@ConditionalOnBean注解是当Spring容器中有某个Bean时才装配。

这个注解通常用于控制某个Bean的创建和注入,只有当容器中已经存在指定的Bean时,带有该注解的类或方法才会被加载。

使用示例:

@Configuration  
@ConditionalOnBean(name = "userBean")  
public class MyBeanConfig {  
  
    @Bean  
    public MyBean myBean() {  
        return new MyBean();  
    }  
}

在上面的示例中,只有当容器中存在名为"userBean"的Bean时,MyBeanConfig类中的myBean()方法才会被创建和注入。

注意:

@ConditionalOnClass和@ConditionalOnBean都是Spring框架中用于条件化配置的注解,但它们的作用和使用场景有所不同。

@ConditionalOnClass注解用于判断classpath下是否存在某个类。当classpath下存在指定类型的类时,带有该注解的类或方法才会被加载。它通常用于在类路径中引入某个类时进行条件判断。

@ConditionalOnBean注解则用于判断Spring容器中是否存在某个Bean。当容器中有指定类型的Bean时,带有该注解的类或方法才会被加载。它通常用于在Spring容器中已有某个Bean时进行条件判断。

总结来说,@ConditionalOnClass和@ConditionalOnBean都用于条件化配置,但前者用于判断classpath下是否存在某个类,后者用于判断容器中是否存在某个Bean。根据实际需求选择使用适当的注解。

@ConditionalOnMissingBean

@ConditionalOnMissingBean注解用于判断Spring容器中是否存在指定类型的Bean。如果容器中不存在该类型的Bean,那么带有该注解的类或方法才会被加载;否则,将不会加载。

使用示例:

@Configuration  
@ConditionalOnMissingBean(type = "com.example.MyBean")  
public class MyBeanConfig {  
  
    @Bean  
    public MyBean myBean() {  
        return new MyBean();  
    }  
}

在上面的示例中,只有当容器中不存在类型为"com.example.MyBean"的Bean时,MyBeanConfig类中的myBean()方法才会被创建和注入。否则,该Bean将不会被加载。

需要注意的是,@ConditionalOnMissingBean注解通常用于避免多个配置同时注入的风险。对于自定义的配置类,建议加上@ConditionalOnMissingBean注解,以确保只有当容器中不存在指定类型的Bean时才会加载该配置。

注意:

@ConditionalOnMissingClass和@ConditionalOnMissingBean都用于判断当前上下文是否存在某个对象,如果不存在,则实例化一个Bean。然而,它们分别用于判断类和Bean的存在与否。

@ConditionalOnMissingClass用于判断某个类是否存在于classpath中。当指定的类不存在时,带有该注解的类或方法才会被加载。

@ConditionalOnMissingBean用于判断某个Bean是否存在于Spring容器中。当容器中不存在指定类型的Bean时,带有该注解的类或方法才会被加载。

因此,@ConditionalOnMissingClass和@ConditionalOnMissingBean分别用于不同的场景,需要根据具体需求选择使用。

@ConditionalOnSingleCandidate

@ConditionalOnSingleCandidate注解用于检测容器中是否存在匹配的单个候选Bean。只有当容器中只有单个候选Bean时,带有该注解的类或方法才会被加载;否则,将不会加载。

使用示例:

@Configuration  
@ConditionalOnSingleCandidate(MyBean.class)  
public class MyBeanConfig {  
  
    @Bean  
    public MyBean myBean() {  
        return new MyBean();  
    }  
}

在上面的示例中,只有当容器中存在类型为"com.example.MyBean"且只有一个候选Bean时,MyBeanConfig类中的myBean()方法才会被创建和注入。否则,该Bean将不会被加载。

需要注意的是,@ConditionalOnSingleCandidate注解通常用于确保容器中只存在一个指定类型的Bean,以避免多个实例同时存在的情况。对于需要确保单例的Bean,建议使用@ConditionalOnSingleCandidate注解进行条件判断。

@ConditionalOnExpression

@ConditionalOnExpression注解用于根据给定的SpEL(Spring Expression Language)表达式来决定是否加载带有该注解的类或方法。当表达式的结果为true时,该类或方法才会被加载;否则,将不会加载。

使用示例:

@Configuration  
@ConditionalOnExpression("${my.feature.enabled:false}")  
public class MyFeatureConfig {  
  
    @Bean  
    public MyFeature myFeature() {  
        return new MyFeature();  
    }  
}

在上面的示例中,当配置文件中的"my.feature.enabled"属性值为true时,MyFeatureConfig类中的myFeature()方法才会被创建和注入。否则,该Bean将不会被加载。

需要注意的是,@ConditionalOnExpression注解通常用于根据配置文件中的属性值来动态决定是否加载某个类或方法。在实际使用中,需要根据具体的业务需求来设置SpEL表达式,以满足不同的条件判断需求。

@ConditionalOnJava

@ConditionalOnJava注解用于根据当前运行的Java版本决定是否加载带有该注解的类或方法。可以根据不同的Java版本来控制不同版本的Bean的创建和注入。

使用示例:

@Configuration  
@ConditionalOnJava(9)  
public class Java9Config {  
  
    @Bean  
    public MyJava9Bean myJava9Bean() {  
        return new MyJava9Bean();  
    }  
}

在上面的示例中,只有当当前运行的Java版本为9时,Java9Config类中的myJava9Bean()方法才会被创建和注入。否则,该Bean将不会被加载。

需要注意的是,@ConditionalOnJava注解只能检测当前运行的Java版本,而不能检测其他已安装的Java版本。如果需要检测其他版本的Java,可以使用其他条件判断注解或通过其他方式进行检测。

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

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

相关文章

3.5每日一题(求齐次方程组的特解)

1、判断类型选择方法:看出为齐次方程(次幂都一样) 2、 化为变量可分离;按变量可分离的方法求出通解(此题等式两边同时除以 x ) 3、把x1,y0带入通解,定常数C,求出特解 …

Android 优质的UI组件汇总

1、RuleView :Android自定义标尺控件(选择身高、体重等) 链接:https://github.com/cStor-cDeep/RuleView 2、DashboardView :Android自定义仪表盘View,仿新旧两版芝麻信用分、炫酷汽车速度仪表盘 链接:https://git…

业务连续性的重要性及关键因素

在今天的竞争激烈的商业环境中,保持业务连续性至关重要。业务连续性是指企业能够在面对各种不可预测的挑战和灾难情况下,保持运营,提供产品和服务,以确保客户满意度和可持续发展。本文将探讨业务连续性的重要性、关键因素和最佳实…

探营云栖大会:蚂蚁集团展出数字人全栈技术,三大AI“机器人”引关注

一年一度的科技盛会云栖大会将于10月31日正式开幕。30日,记者来到云栖大会展区探营,提前打卡今年上新的“黑科技”。 记者在蚂蚁集团展馆看到,超1亿人参与的亚运“数字火炬手”全栈技术首次公开展示,还可体验基于数字人技术的“数…

【工具使用】NPS内网穿透工具介绍

文章目录 前言一、内网穿透二、NPS概述三、NPS原理四、NPS服务器搭建(一)云服务器配置 五、NPS内网穿透演示(一)演示案例一(二)演示案例二 六、NPS内网穿透检测建议(一)流量监控(二)流量协议分析(三)网络行为异常检测 七、NPS内网穿透防范建议(一)阻止或隔离流量(二)更新和强化…

GitHub经常打不开或者访问解决办法

访问慢或无法访问的原因:DNS解析是最为基础的一个环节。由于Github的服务器在全球各地,域名解析所需的时间也会不同,这就导致了在特定地区可能会出现Github无法正常访问的情况。 解决:查询到github对应的IP,然后在host…

Java - JDK演变之路和JDK21新特性

Java - JDK演变之路和JDK21新特性 前言一. JDK演变之路JDK9 新特性(2017年9月)JDK10 新特性(2018年3月)JDK11 新特性(2018年9月 - LTS版本)☆JDK12 新特性(2019年3月)JDK13 新特性&a…

《低代码指南》——我想将维格云与别的系统打通,自动同步数据,怎么实现?

与其他系统打通的3种形式 ​ 人工复制粘贴:操作难度低,时效性差,适合于少量数据定时更新Excel导入:可追加导入,作难度低,时效性差,适和于定期更新数据API对接:可实现实时数据对接,有一定操作门槛API对接的3种方法​ 维格机器人:可以通过维格机器人直接调用对接系统的…

MES与AGV对接浅谈

昨天分享一些有关数字工厂与立体库的对接经验,随着智能物料技术的越来越成熟,硬件设施成本的下降,很多制造业在工厂规划时已经开始考虑在物料搬运、物料配送等使用无人化的智能搬运机器。今天聊聊有关在智能工厂实施中MES与AGV的对接方式一些…

VM搭建虚拟机(CentOS镜像)

文章目录 VMware下载安装CentOS往下滑,找到alternative downloads向下滑找到Archived Versions进入isos目录点击x86/64选择镜像文件 下载很慢emo然后百度网盘直接下载就好 搭建虚拟机选择cenos下载目录,并选择稍后安装选择Linux,找到cenos7版…

跨域解决方案有哪些?

跨域 因为浏览器出于安全考虑&#xff0c;有同源策略。也就是说&#xff0c;如果协议、域名或者端口有一个不同就是跨域&#xff0c;Ajax 请求会失败。 我们可以通过以下几种常用方法解决跨域的问题 JSONP JSONP 的原理很简单&#xff0c;就是利用 <script> 标签没有…

基于轻量级yolov5n开发构建涵洞场景下洞体墙体缺陷病害检测分割系统

在前文&#xff1a; 《AI助力隧道等洞体类场景下水泥基建缺陷检测&#xff0c;基于DeeplabV3Plus开发构建洞体场景下壁体建筑缺陷分割系统》 我们基于DeepLabv3Plus尝试构建了洞体类建筑缺损病害问题分割系统&#xff0c;本文的核心思想是想要基于yolo这一经典的模型来开发构…

VIRTIO-Virtual IO Based On VPP/DPDK at front

简介 虚拟化技术是云计算的基石&#xff0c;是构建上层弹性计算、弹性存储、弹性网络的基本成份。所谓虚拟化&#xff0c;即对计算所需的资源进行模拟&#xff0c;提供与物理资源一般无二的特性和运行环境。如Qemu将整个VM所需环境进行虚拟化&#xff1a;一个Qemu进程代表一台…

【Vue】初步认识<script setup>语法糖和组合式 API

▒ 目录 ▒ &#x1f6eb; 导读需求开发环境 1️⃣ &#x1f6eb; 导读 需求 最近写代码的时候&#xff0c;发现<script setup>这样的代码&#xff0c;没见过&#xff0c;好奇&#xff0c;想知道。 所以就有了这篇文章。 很多文章都说setup是vue3的特权。但是&#xff…

2023.10.29 关于 HashTable 和 ConcurrentHashMap 区别

目录 HashTable ConcurrentHashMap 优化点一 优化点二 优化点三 优化点四 不关键的小区别 HashTable HashMap 和 HashTable 都是常见的哈希表数据结构&#xff0c;用于存储键值对 注意&#xff1a; HashMap 是线程不安全的HashTable 是线程安全的&#xff0c;其关键方法…

MapBox获取点位高程的三种方式

以下提供了三种方法和思路 1&#xff0c;通过mapbox全球dem数据获取高程 这里我们利用了mapbox的tilequery 官网地址在这里 https://docs.mapbox.com/api/maps/tilequery/ 以下是示例代码&#xff0c;这个方式是简单快捷&#xff0c;缺点就是精度不高&#xff0c;大概是以10m…

世界前沿技术发展报告2023《世界航空技术发展报告》(五)直升机技术

&#xff08;五&#xff09;直升机技术 1.常规直升机技术1.1 北约六国联合启动下一代旋翼飞行器能力项目1.2 美国和法国重视发展有人/无人直升机编组能力1.3 美国“黑鹰”直升机完成不载人全自主飞行 2.新概念直升机技术2.1 美国“劫掠者”X型直升机参与陆军“未来攻击侦察机”…

【电路笔记】-交流电感和感抗

交流电感和感抗 文章目录 交流电感和感抗1、概述1.1 电感1.2 电感器 2、频率特性2.1 电抗(Reactance)2.2 相移2.3 感应现象 3、RL滤波器4、总结 在之前有 交流电阻的文章中&#xff0c;我们已经看到电阻器在正常频率下的直流或交流状态下的行为是相同的。 然而&#xff0c;其他…

吃透进程地址空间,理清OS内存管理机制

文章目录 一、前言二、细说进程地址空间1、一段测试的代码2、引入地址空间① 富豪与他的私生子&#x1f468;② 38线竟是这么来的&#xff01;③ 地址空间的深层理解 三、分页 & 虚拟地址空间1、页表的概念2、疑难解答&#xff1a;为何父子进程没有发生同步修改&#xff1f…

注意点细节

部署esxi: VLAN 装esxi的时候如果没有设置trunk就不要设置VLAN&#xff0c; 否则无法访问 。 设置了trunk接口才设置VLAN&#xff0c;否则无法访问 部署esxi: DNS dns服务器配置&#xff1a; esxi 上的配置 部署ESXI &#xff1a;RAID 生成环境中需要先设置RAID 作为系统…