SpringBoot条件注解全解析:核心作用与使用场景详解
目录
- 引言
- 一、条件注解的核心机制
- 二、SpringBoot内置条件注解详解
- 1、@ConditionalOnClass和@ConditionalOnMissingClass
- 2、@ConditionalOnBean和@ConditionalOnMissingBean
- 3、@ConditionalOnProperty
- 4、@ConditionalOnWebApplication和@ConditionalOnNotWebApplication
- 5、@ConditionalOnExpression
- 6、@ConditionalOnResource
- 7、@ConditionalOnJava
- 8、@ConditionalOnSingleCandidate
- 三、组合使用条件注解
- 四、条件注解的底层原理
- 总结
引言
Spring Boot 的条件注解(Conditional Annotations)是自动配置(Auto-Configuration)的核心机制之一。它们允许开发者根据特定的条件动态决定是否加载某个Bean或配置类,从而实现灵活的“按需配置”。本文将系统梳理所有常用的条件注解,结合代码示例说明其作用与使用场景。
一、条件注解的核心机制
元注解:@Conditional作为所有条件注解的基础,@Conditional通过实现Condition接口的matches()方法进行条件判断。若条件满足,则Bean或配置类生效;否则跳过。
示例:自定义条件类检查JdbcTemplate是否存在
public class JdbcTemplateCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return ClassUtils.isPresent("org.springframework.jdbc.core.JdbcTemplate", context.getClassLoader());}}
二、SpringBoot内置条件注解详解
SpringBoot基于@Conditional扩展了以下常用注解,覆盖了大多数自动化配置场景。
1、@ConditionalOnClass和@ConditionalOnMissingClass
作用:根据类路径中是否存在指定类来决定是否生效典型场景:自动配置类中检查依赖库是否存在- 示例:当项目中引入
Hibernate时,自动配置JPA相关Bean
@Configuration
@ConditionalOnClass({ DataSource.class, EntityManager.class })
public class JpaAutoConfiguration {// 当类路径存在DataSource和EntityManager时生效
}
2、@ConditionalOnBean和@ConditionalOnMissingBean
作用:根据容器中是否存在指定Bean来决定是否生效典型场景:避免重复注册Bean,或为默认Bean提供自定义覆盖- 示例:当用户未自定义
DataSource时,注册默认数据源
@Bean
@ConditionalOnMissingBean(DataSource.class)
public DataSource defaultDataSource() {return new HikariDataSource();
}
3、@ConditionalOnProperty
作用:根据配置文件(如application.yml)中的属性值决定是否生效典型场景:功能开关、多环境配置切换- 示例:根据配置启用缓存功能
@Configuration
@ConditionalOnProperty(name = "app.cache.enabled", havingValue = "true")
public class CacheConfig {// 当app.cache.enabled=true时加载
}
4、@ConditionalOnWebApplication和@ConditionalOnNotWebApplication
作用:根据当前应用是否为Web应用决定是否生效典型场景:区分Web环境与非Web环境(如批处理任务)- 示例:仅在Web应用中注册MVC组件
@Configuration
@ConditionalOnWebApplication
public class WebMvcConfig {// 仅在Web环境中生效
}
5、@ConditionalOnExpression
作用:通过SpEL表达式组合复杂条件典型场景:需要同时满足多个条件或复杂逻辑判断- 示例:同时满足属性开关和类路径存在时生效
@Bean
@ConditionalOnExpression("${app.feature.enabled} && T(com.example.SomeClass).isAvailable()"
)
public FeatureBean featureBean() {return new FeatureBean();
}
6、@ConditionalOnResource
作用:检查指定资源文件是否存在典型场景:根据配置文件或密钥文件的存在性加载配置- 示例:存在
config-override.properties时覆盖默认配置
@Configuration
@ConditionalOnResource(resources = "classpath:config-override.properties")
public class OverrideConfig {// 当类路径存在该文件时生效
}
7、@ConditionalOnJava
作用:根据当前JVM版本决定是否生效典型场景:兼容不同Java版本的特性- 示例:仅当JVM版本为11或更高时启用模块化配置
@Configuration
@ConditionalOnJava(range = ConditionalOnJava.Range.EQUAL_OR_NEWER, value = JavaVersion.ELEVEN)
public class Java11Config {// Java 11+ 环境下生效
}
8、@ConditionalOnSingleCandidate
作用:当容器中存在且只有一个指定类型的Bean时生效典型场景:自动配置依赖特定单一Bean的场景- 示例:当只有一个
DataSource时自动配置事务管理器
@Bean
@ConditionalOnSingleCandidate(DataSource.class)
public PlatformTransactionManager transactionManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);
}
三、组合使用条件注解
- 多个条件注解可组合使用,实现更精细的控制
@Configuration
@ConditionalOnClass({RedisClient.class})
@ConditionalOnProperty(name = "app.redis.enabled", matchIfMissing = true)
public class RedisAutoConfig {// 当RedisClient存在且配置开启(或未配置)时生效
}
四、条件注解的底层原理
Spring Boot在启动时,通过条件注解解析器(如ConditionEvaluator)扫描所有配置类,结合以下步骤实现条件装配
条件收集:解析配置类上的条件注解,生成对应的Condition实例条件匹配:调用matches()方法,结合类路径、Bean容器状态、环境变量等进行判断动态注册:仅注册满足条件的Bean,未满足的配置类会被跳过
总结
Spring Boot的条件注解为开发者提供了强大的动态配置能力,理解其原理和适用场景是构建灵活、可扩展应用的关键。通过合理组合这些注解,可以实现“智能”的自动配置逻辑,同时避免冗余代码。实际开发中,建议结合Spring Boot的自动配置源码(如spring-boot-autoconfigure模块)深入学习。
相关文章:
SpringBoot条件注解全解析:核心作用与使用场景详解
目录 引言一、条件注解的核心机制二、SpringBoot内置条件注解详解1、ConditionalOnClass和ConditionalOnMissingClass2、ConditionalOnBean和ConditionalOnMissingBean3、ConditionalOnProperty4、ConditionalOnWebApplication和ConditionalOnNotWebApplication5、ConditionalO…...
android11通过白名单卸载安装应用
目录 1.源码路径: 2.准备文件package.conf: 3.安装方法installPackagesLI 4.卸载方法deletePackageX 1.源码路径: frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java public static final String WHITELIST_PATH="/data/misc/pa…...
大M法处理非线性约束线性化
在电力系统优化问题中,大M法(Big M Method)是一种经典的处理非线性约束线性化的技术,尤其适用于混合整数线性规划(MILP)问题。 其核心思想是通过引入足够大的常数M和辅助变量(如二元变量或松弛…...
【网络安全】谁入侵了我的调制解调器?(一)
文章目录 我被黑了159.65.76.209,你是谁?黑客攻击黑客?交出证据三年后我被黑了 两年前,在我家里使用家庭网络远程办公时,遇到了一件非常诡异的事情。当时,我正在利用一个“盲 XXE 漏洞”,这个漏洞需要借助一个外部 HTTP 服务器来“走私”文件。为了实现这一点,我在 AW…...
【Nokia 7360 ISAM局端】7360局端升级步骤
引言 Nokia 7360 ISAM局端是当前主流的OLT局端之一,在测试ONT产品中经常需要对接7360局端,特别是欧美等海外运营商。测试过程中经常需要升级OLT版本,以便对齐前方客户的现网环境。本文介绍将Nokia 7360 ISAM局端升级到L6GPAA65.669版本的详细步骤。 连接带外管理口 将维护…...
await 在多线程,子线程中的使用
await 在多线程,子线程中的使用 await self.send_reply(user, user, user, auto_content, reply) 这行代码是在一个异步函数里调用类的实例方法 send_reply 代码含义 1. await 关键字 在 Python 的异步编程里,await 关键字的作用是暂停当前异步函数的执行,直到 await 后…...
主数据管理:企业数字化转型的 “数据基石“ 如何为 AI 筑基?
引言:当数据成为新石油,谁在炼制 "高纯度燃料"? 在数字化转型的浪潮中,企业宛如行驶在数据海洋中的巨轮,AI 则是驱动巨轮破浪前行的引擎。但引擎能否高效运转,取决于燃料的纯度 —— 这正是主数…...
使用源码编译安装golang的docker版
编译规则 1.4之前用C写的,1.4可编译后续一直到1.9版本,后续版本实现了自举,后续版本是go写的,基本上相互低2个版本能编译出新版本。 Go < 1.4:C 工具链。 1.5 < Go < 1.19:Go 1.4 编译器。 1.20…...
使用 chromedriver 实现网络爬虫【手抄】
1、引用 selenium 包 <dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.29.0</version> </dependency> <dependency><groupId>org.seleniumhq.seleniu…...
Linux之 grep、find、ls、wc 命令
Linux之 grep、find、ls、wc 命令 “ 在 Linux 世界中,命令行是不可或缺的一部分,而掌握一些常用的命令可以帮助你更有效率地管理文件和系统。本文将为你介绍四個基礎而强大的 Linux 命令:grep、find、ls 和 wc,带你开启高效文件…...
AI 模型高效化:推理加速与训练优化的技术原理与理论解析
AI 模型高效化:推理加速与训练优化的技术原理与理论解析 文章目录 AI 模型高效化:推理加速与训练优化的技术原理与理论解析一、推理加速:让模型跑得更快的“程序员魔法”(一)动态结构自适应推理:像人类一样…...
c++STL——vector的使用和模拟实现
文章目录 vector的使用和模拟实现vector的使用vector介绍重点接口的讲解迭代器部分默认成员函数空间操作增删查改操作迭代器失效问题(重要)调整迭代器 vector的模拟实现实现的版本模拟实现结构预先处理的函数尾插函数push_backswap函数赋值重载size函数reserve函数 迭代器默认成…...
git更新的bug
文章目录 1. 问题2. 分析 1. 问题 拉取了一个项目后遇到了这个问题, nvocation failed Server returned invalid Response. java.lang.RuntimeException: Invocation failed Server returned invalid Response. at git4idea.GitAppUtil.sendXmlRequest(GitAppUtil…...
github | 仓库权限管理 | 开权限
省流版总结: github 给别人开权限:仓库 -> Setting -> Cllaborate -> Add people GitHub中 将公开仓库改为私有:仓库 -> Setting -> Danger Zone(危险区) ->Change repository visibility( 更改仓…...
MQTT客户端核心架构解析:clients.h源码深度解读
MQTT客户端核心架构解析:clients.h源码深度解读 一、头文件概览与设计哲学 clients.h作为MQTT客户端核心数据结构定义文件,体现了以下设计原则: 分层架构:网络层/协议层/业务层解耦状态管理:通过状态机实现复杂协议…...
uniapp自定义底部导航栏,解决下拉时候顶部空白的问题
一、背景 最近使用uniapp开发微信小程序,因为使用了自定义的顶部导航栏,所以在ios平台上(Android未测试)测试的时候,下拉的时候会出现整个页面下拉并且顶部留下大片空白的问题 二、任务:解决这个问题 经…...
C++学习之密码学知识
目录 1.文档介绍 2.知识点概述 3.项目准备 4.序列化介绍 5.项目中基础组件介绍 6.基础模块在项目中作用 7.项目中其他模块介绍 8.加密三要素 9.对称加密和非堆成加密 10.对称和非对称加密特点 11.堆成加密算法des 12.des对称加密算法 13.对称加密算法aes 14.知识点…...
力扣 797. 所有可能的路径
题目 给你一个有 n 个节点的 有向无环图(DAG),请你找出所有从节点 0 到节点 n-1 的路径并输出(不要求按特定顺序) graph[i] 是一个从节点 i 可以访问的所有节点的列表(即从节点 i 到节点 graph[i][j]存在一…...
第二篇:linux之Xshell使用及相关linux操作
第二篇:linux之Xshell使用及相关linux操作 文章目录 第二篇:linux之Xshell使用及相关linux操作一、Xshell使用1、Xshell安装2、Xshell使用 二、Bash Shell介绍与使用1、什么是Bash Shell(壳)?2、Bash Shell能干什么?3、平时如何使…...
全自动驾驶(FSD,Full Self-Driving)自动驾驶热点技术的成熟之处就是能判断道路修复修路,能自动利用类似“人眼”的摄像头进行驾驶!值得学习!
全自动驾驶(FSD,Full Self-Driving)软件是自动驾驶领域中的热点技术,其核心目标是实现车辆在各种复杂交通环境下的安全、稳定、高效自动驾驶。FSD软件的技术核心涉及多个方面的交叉技术,下面将详细分析说明其主要核心技…...
SpringBoot项目动态加载jar 实战级别
网上也找到类似的文章,但是基本都不到实用级别,就是不能直接用。在参照网上的文章及与AI沟通N次后终于完善可以在实际项目上 创建jar文件动态加载类 Component Slf4j public class PluginRegistry {Autowiredprivate GenericApplicationContext applicat…...
一种改进的CFAR算法用于目标检测(解决多目标掩蔽)
摘要 恒虚警率(CFAR)技术在雷达自动检测过程中起着关键作用。单元平均(CA)CFAR算法在几乎所有的多目标情况下都会受到掩蔽效应的影响。最小单元平均(SOCA)CFAR算法仅当干扰目标位于参考窗口的前后方时才具有…...
无人机+智能监控:石油管道巡检迈入“空中智慧时代”
引言:安全与效率的双重革命 在广袤的沙漠、崎岖的山脉或人迹罕至的冻土带,石油管道的安全巡检曾是一项耗时耗力且风险极高的任务。如今,随着无人机巡检技术与视频监控管理平台的深度融合,石油行业正迎来一场智能化变革——从“人巡…...
Python内置函数---anext()
用于异步迭代器的核心工具,专为处理异步数据流设计。 1. 基本语法 await anext(async_iterator, default) 参数: async_iterator :实现了异步迭代协议的对象(如异步生成器、异步迭代器类)。 default (可选…...
4.17学习总结
完成135. 分发糖果 - 力扣(LeetCode)的算法 学习了字节缓冲流和字符缓冲流,了解了底层的原理,...
【gpt生成-其一】以go语言为例,详细描述一下 :语法规范BNF/EBNF形式化描述
在 Go 语言中通过 EBNF 形式化描述语法规范需要结合语言规范文档的结构,以下是详细实现方法及标准规范示例: 一、Go 语法规范结构(基于 Go 1.21 标准) ebnf 复制 // 基础元素定义 letter "A" ... "Z&quo…...
用cython将python程序打包成C++动态库(windows+Vistual Studio2017平台)
作为一名程序员我们都知道Python的库可能要比C的丰富的多特别是在算法方面,但是有的时候我们的工程是用C开发的,我们又像用Python的这个库那怎么办呢?如果直接调.py程序,工程中代码有.py又有.cpp显得工程很杂乱。那么我么可以借助…...
三层交换机SVI功能(交换机虚拟接口)实现各个实训室电脑网络可互通,原本是独立局域网
三层交换机 SVI功能(交换机虚拟接口) 实现VLAN路由 需求 :各实训室使用独立局域网,即每个实训有自己的IP网段, 每个实训室只有内部互相访问。 需求:为了加强各实训室学生的交流,学校要求我们…...
class的访问器成员
class的访问器成员 本质是 class 的语法糖 等价于对象的defineProperty对象里面也能使用 class Product{constructor(count, price){this.count count;this.price price;}get total(){ // 相当于getterreturn this.count * this.price;}}const product new Product(10, 10…...
vue入门:路由 router
文章目录 介绍安装配置路由模式嵌套路由路由传参编程式导航路由懒加载 底层原理 介绍 vue2 vue router API vue3 vue router API Vue Router 是 Vue.js 的官方路由管理器,它允许你通过不同的 URL 显示不同的组件,从而实现单页面应用(SPA&a…...
