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

前言

在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.mzph.cn/news/124445.shtml

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

相关文章

51单片机-点阵屏led

代码配置 这样就能选择每一列哪个亮了 进行位选,段清零,这样就不会影响多列同时了 实现动画 1、使用文字摸提取文件,提取图案的16进制表示数组 offest作为偏移量,count作为计时。count10,偏移量加1,就相当于得到下一…

毕业设计基于SpringMVC+Mybatis+Bootstrap的电影院管理系统源码+数据库

<<电影院管理系统>> 电影院管理系统&#xff1a;SpringMVCJSPTomcatMybatisBootstrapJqueryAnimateCSSLayerJS 项目部署&#xff1a;该项目是IDEA版本&#xff0c;Maven项目 前端依赖&#xff1a; Bootstrap-3.4.1Animate.css- 4.1.1Jquery-3.6.0Layer-v3.5.1B…

自学爬虫—作业1—requests模块

视频&#xff1a; 要求&#xff1a; 肯德基地址查询&#xff0c;爬某个关键字&#xff0c;获取下面的所有page的信息&#xff0c;存到一个json或者txt。 代码&#xff1a; 关键点&#xff0c;&#xff08;1&#xff09;每一个ajax的请求第一个键值对就是所有获得的地址的总数…

Python语言: 切片的使用

切片的本质&#xff1a;通过切片来截取指定的元素&#xff0c;形成一个新的容器。 切片的具体阐释&#xff1a; 此切片非切片面包的切片&#xff0c;而是python语言中的切片。切片&#xff1a;顾名思义&#xff0c;就是把整块的东西分割开来。python语言中的切片是把一个容器截…

微信小程序 slot 不显示

问题:创建组件&#xff0c;使用带名字的slot&#xff0c;页面调用组件使用slot不显示 源码&#xff1a; 组件xml <view class"p-item br24" style"{{style}}"><slot name"right" wx:if"{{!custBottom}}"></slot>&l…

java商城免费搭建 VR全景商城 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

maven环境变量,安装源,本地仓库配置

1. maven环境变量 我这里用的是idea自带的maven 数值为&#xff1a; D:\software\computer_software\java\IDEAJ\IDEAJ2021.2.1\IntelliJ IDEA 2021.2.1\plugins\maven\lib\maven3\bin 2. 安装源更换为阿里云&#xff08;我不知道清华源是什么网址&#xff0c;网上也没查到&am…

分布式:一文吃透分布式事务和seata事务

目录 一、事务基础概念二、分布式事务概念什么是分布式事务分布式事务场景CAP定理CAP理论理解CAPCAP的应用 BASE定理强一致性和最终一致性BASE理论 分布式事务分类刚性事务柔性事务 三、分布式事务解决方案方案汇总XA规范方案1&#xff1a;2PC第一阶段&#xff1a;准备阶段第二…

【计算机网络】什么是HTTPS?HTTPS为什么是安全的?

【面试经典题】 前言&#xff1a; HTTP最初的设计就是用于数据的共享和传输&#xff0c;并没有考虑到数据的安全性&#xff0c;如窃听风险&#xff0c;篡改风险和冒充风险。HTTPS是在 HTTP 的基础上引入了一个加密层。HTTPS通过数据加密&#xff0c;数据完整性检验和身份认证…

【Java 进阶篇】Java登录案例详解

登录是Web应用程序中常见的功能&#xff0c;它允许用户提供凭证&#xff08;通常是用户名和密码&#xff09;以验证其身份。本文将详细介绍如何使用Java创建一个简单的登录功能&#xff0c;并解释登录的工作原理。我们将覆盖以下内容&#xff1a; 登录的基本概念创建一个简单的…

安装Jdk 报错 ,Java SE Development Kit 8 Update 202(64-bit)安装完毕之前,向导被中断

具体原因没有找到&#xff0c;估计是由于jdk 没有删干净导致的&#xff0c;我的处理方法是&#xff0c;将 Java的注册表全然后手动安装 Jdk和导入注册表&#xff08;在同事那里获取jdk文件 压缩包&#xff0c;并将 java的注册表导出&#xff0c;放在自己电脑上使用。&#xff0…

ChatGPT扩展系列之ChatExcel

文章目录 ChatGPT扩展系列之ChatExcel对某一列的文字进行处理对数据进行排序对数据进行计算微软官方又推出Excel AI插件ChatGPT扩展系列之ChatExcel 自从ChatGPT很空出世之后,很多基于ChatGPT的应用便如雨后春笋般应用而生,这些应用的底层本质就是利用了ChatGPT对自然语言的…

M1本地部署Stable Diffusion

下载安装 参考博客: 在Mac上部署Stable Diffusion&#xff08;超详细&#xff0c;AI 绘画入门保姆级教程&#xff09; 安装需要的依赖库 brew install cmake protobuf rust python3.10 git wget 可能中途会存在下载报错或者下载卡主的问题,需要切国内源 brew进行替换源: …

树莓派 qt 调用multimedia、multimediawidgets、serialport、Qchats

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、测试11.命令安装出现错误 二、测试21. 安装 Qt Charts&#xff1a;2. 安装 Qt Multimedia 和 Qt MultimediaWidgets&#xff1a;3. 安装 Qt SerialPort&…

C/S架构和B/S架构

1. C/S架构和B/S架构简介 C/S 架构&#xff08;Client/Server Architecture&#xff09;和 B/S 架构&#xff08;Browser/Server Architecture&#xff09;是两种不同的软件架构模式&#xff0c;它们描述了客户端和服务器之间的关系以及数据交互的方式。 C/S 架构&#xff08…

Springboot的Container Images,docker加springboot

Spring Boot应用程序可以使用Dockerfiles容器化&#xff0c;或者使用Cloud Native Buildpacks来创建优化的docker兼容的容器映像&#xff0c;您可以在任何地方运行。 1. Efficient Container Images 很容易将Spring Boot fat jar打包为docker映像。然而&#xff0c;像在docke…

【已解决】取消 el-aside 默认宽度|不再用 !important

文章目录 问题原因解决方法 问题原因 element-ui 的 el-aside 组件有 width props&#xff0c;默认为 300px 解决方法 给 el-aside 标签添加 width"" width 为空&#xff08;不正确的css样式/写法&#xff09;样式将会失效。 就可以在 style 中修改 el-aside 宽…

C# “依赖注入” 中的 “三种生命周期”

&#x1f680;简介 依赖注入&#xff08;Dependency Injection&#xff0c;简称DI&#xff09;是一种实现控制反转&#xff08;IoC&#xff09;的技术&#xff0c;用于减少代码之间的耦合度。通过依赖注入&#xff0c;一个类可以从外部获取其依赖的对象&#xff0c;而不是自己…

Hudi系列文章7-RFC24 Flink 写入流程优化

文章目录 前言问题背景瓶颈与解决方案瓶颈一解决方法工作流程&#xff1a;精准一次语义容灾CoorinatorCheckpoint如何配合使用StreamWriteOperatorCoordinator CheckpointedFunctionStreamWriteFunctionInstant 提前生成问题 瓶颈二问题解决方案BucketAssignerBucketWriter 重点…

Java自学者怎么写简历?

Java自学者怎么写简历&#xff1f; 首先&#xff0c;有技术实力的人绝对不会问这个问题。虽然你是自学的&#xff0c;但是一定要有项目&#xff01;没有项目都是空谈。最近很多小伙伴找我&#xff0c;说想要一些Java资料&#xff0c;然后我根据自己从业十年经验&#xff0c;熬夜…