Spring Boot 自动装配不是魔法:@ConditionalOnMissingBean 失效那天,我们重读了 spring.factories 的加载顺序
引子我们做内部数据访问 starter 的时候封装了一个默认DataSource用ConditionalOnMissingBean(DataSource.class)留了个用户自定义就覆盖我的后门。本以为万事大吉。结果上线两周后测试库密码轮换监控里突然冒出一堆连不上测试库的报错——可我们业务代码明明白白用的是自己的DataSource啊。最后用ctx.getBeansOfType(DataSource.class)一查容器里竟然有 2 个 DataSource bean。那个本该缺席的默认 DataSource 悄悄注册了还默默建了一个 HikariCP 连接池连着测试库。这次事故逼我们把 Spring Boot 自动装配的加载顺序啃了一遍。结论是ConditionalOnMissingBean不是看全局有没有这个 bean它只看到当前这一步为止已经注册了哪些 bean——顺序错了它就会失手。这篇文章把自动装配机制和这个顺序坑讲透。问题自动装配到底装了什么你写的SpringBootApplication是个复合注解真正负责自动装配的是它身上的EnableAutoConfiguration。展开看自动装配就干了一件事在应用启动时按条件把一大批预先写好的 Configuration注册进容器。这些预先写好的配置类从哪来Spring Boot 2.6 及更早版本靠SpringFactoriesLoader读取所有 jar 包里META-INF/spring.factories文件的EnableAutoConfiguration键# spring.factoriesSpring Boot 2.6 及之前 org.springframework.boot.autoconfigure.EnableAutoConfiguration\ com.example.autoconfig.RedisAutoConfiguration,\ com.example.autoconfig.DataSourceAutoConfiguration而每个XxxAutoConfiguration类头上挂满了Conditional系列注解决定在当前环境下这个类到底装不装、里面的 bean 到底建不建。所谓自动本质是按条件批量注册配置 用户可覆盖。版本提醒Spring Boot 2.7 起spring.factories被标记弃用3.0 直接移除改用在META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports里列全类名。如果你在 3.x 上还按老写法放spring.factories自动装配类根本不会被加载——这是另一个高频坑。原理一自定义一个 starter 的自动装配一个最小可工作的自动装配类长这样以 Redis 为例Configuration ConditionalOnClass(RedisTemplate.class) // ① 类路径有 RedisTemplate 才装配 ConditionalOnProperty(prefix app.redis, name enabled, havingValue true, matchIfMissing true) // ② 开关默认开 public class RedisAutoConfiguration { Bean ConditionalOnMissingBean(RedisTemplate.class) // ③ 用户没定义才用这个默认 public RedisTemplateString, Object redisTemplate(RedisConnectionFactory factory) { RedisTemplateString, Object t new RedisTemplate(); t.setConnectionFactory(factory); t.setKeySerializer(new StringRedisSerializer()); t.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return t; } }逐行解释第 2 行ConditionalOnClass(RedisTemplate.class)只有项目真的引入了spring-data-redisRedisTemplate在类路径上才装配这个类。你的 starter 被一个没用 Redis 的项目依赖时它自动隐身不会因缺类而启动报错。这是自动装配不污染别人的关键。第 3 行ConditionalOnProperty用配置项app.redis.enabled当总开关matchIfMissing true表示不配也默认开启。第 8 行ConditionalOnMissingBean(RedisTemplate.class)这才是用户可覆盖的后门——容器里到此刻还没有RedisTemplate类型的 bean才注册默认的有了就跳过。原理二Conditional 系列是自动装配的灵魂Spring Boot 提供了一整套条件注解自动装配类就是靠它们拼出按需装配的Configuration ConditionalOnWebApplication(type Type.SERVLET) // 仅 Servlet Web 环境才装 ConditionalOnClass(DispatcherServlet.class) // 类路径有这个类才装 ConditionalOnProperty(feature.x.enabled) // 配置开关为 true AutoConfigureAfter(DataSourceAutoConfiguration.class) // 排在数据源自动装配之后 public class XAutoConfiguration { Bean ConditionalOnMissingBean public XService xService() { return new XService(); } }逐行解释第 2 行ConditionalOnWebApplication你的 starter 被一个纯后端批处理程序依赖时它不是 Web 环境整个配置类跳过避免引入 servlet 相关 bean 导致冲突。第 4 行ConditionalOnProperty不带havingValue时配置存在且非false即生效常用来做功能开关。第 5 行AutoConfigureAfter是顺序编排很多自动装配之间有依赖比如用到DataSource的配置必须排在DataSourceAutoConfiguration之后否则它依赖的DataSourcebean 还没建好。这里的After/Before/Order只影响自动装配类之间的相对顺序不影响普通的ComponentScanbean。第 9 行ConditionalOnMissingBean不带参数时默认按方法返回类型XService判断。原理三ConditionalOnMissingBean 的检测窗口陷阱这是栽我们的根因必须讲清。ConditionalOnMissingBean检查的是到当前 bean 定义处理时刻为止容器中已存在的 bean而不是最终的全部 bean。而 Spring 处理 bean 定义是有先后顺序的先处理ComponentScan扫到的Component/Configuration包括你主应用包下的业务配置。再处理自动装配类EnableAutoConfiguration引入的那批且自动装配类之间按AutoConfigureBefore/After/Order排序。所以如果用户的自定义 bean 是通过ComponentScan注册的最常见写在主应用包下它先于自动装配处理ConditionalOnMissingBean能看到它正确缺席——这是正常情况。出问题的是下面这种// 业务模块里把自定义 DataSource 写在一个 Configuration 里注意不是 Component Configuration public class BizDataSourceConfig { Bean public DataSource dataSource() { // 业务自己的 DataSource return new HikariDataSource(...); } } // starter 里 Configuration ConditionalOnMissingBean(DataSource.class) // 本以为能检测到业务的 dataSource public class StarterDataSourceAutoConfig { Bean public DataSource dataSource() { return new HikariDataSource(...); // 结果也注册了 } }逐行解释第 3 行业务dataSource写在BizDataSourceConfig这个普通Configuration里。如果该配置类因为某种排序原因在 starter 的自动装配类之后才被处理比如 starter 用了AutoConfigureBefore抢先或业务配置本身又被别的自动装配Import延迟那么处理 starter 的ConditionalOnMissingBean那一刻业务的dataSource还没注册ConditionalOnMissingBean判定没有→ 默认 bean 被注册。第 12 行 starter 的dataSource于是也注册进去。由于业务的Primary让注入走业务那个表面上能跑但容器里实际上有 2 个 DataSource bean其中一个默默连着测试库、建着多余的连接池——直到密码轮换才炸出来。换句话说ConditionalOnMissingBean的Missing是时序相关的没看到不等于真的没有。这是自动装配最容易踩的顺序雷。我们的修复与验证定位靠这一行// 启动后 / 单元测试里打印确认到底注册了几个 MapString, DataSource dsMap ctx.getBeansOfType(DataSource.class); System.out.println(DataSource 数量 dsMap.size()); // 预期 1实际 2 dsMap.forEach((name, ds) - System.out.println(name - ds));确认有 2 个后修复有两招招一推荐把业务的自定义DataSource放在主应用包下、用Component/Configuration走组件扫描保证它先于自动装配被注册这样ConditionalOnMissingBean能正常看到它并让默认 bean 缺席。招二在业务配置类上显式声明AutoConfigureBefore(StarterDataSourceAutoConfig.class)强制它在 starter 自动装配之前处理。但AutoConfigureBefore只对自动装配类生效业务配置得先变成自动装配类进spring.factories/ imports 文件才行代价较大。我们选了招一把业务DataSource挪进主应用包下的Configuration问题立刻消失getBeansOfType回到 1 个那个连测试库的冗余连接池也随之消失。我的取舍判断自动装配是便利不是魔法更不该是黑盒用别人 starter 时遇到多了一个 bean配置没生效第一反应应该是getBeansOfType(XXX.class)看容器里到底有几个而不是盲目加Primary掩盖。Primary 能解决注入冲突但解决不了多余 bean 偷偷建连接池这种资源泄漏。写自己的 starter条件要写全套ConditionalOnClassConditionalOnPropertyConditionalOnMissingBean三件套尽量齐全既不让 starter 污染不需要它的项目也留好用户覆盖的口子。我们那次就是只写了ConditionalOnMissingBean没考虑顺序才埋雷。ConditionalOnMissingBean 别依赖全局唯一的假设它看的是时序窗口内的 bean。如果你的覆盖 bean 定义在一个可能被延后处理的Configuration里它就不可靠。稳妥的做法是让覆盖 bean 走组件扫描主应用包注册。Spring Boot 3.x 务必改用AutoConfiguration.imports文件别再写spring.factories否则自动装配类整批不加载排查起来非常迷惑。总结Spring Boot 自动装配 EnableAutoConfiguration触发 SpringFactoriesLoader或 3.x 的 imports 文件批量加载XxxAutoConfiguration 一堆Conditional决定装不装。它的价值是按需、可覆盖但ConditionalOnMissingBean的Missing是时序相关的——只看处理到当前时刻已注册的 bean。我们的事故正是业务DataSource因排序延后注册导致ConditionalOnMissingBean失手、默认 bean 偷偷注册、冗余连接池连着测试库。排查这类问题永远从getBeansOfType数 bean 开始。思考题你项目里引入的第三方 starter有没有可能偷偷注册了你不想要的 bean挑一个核心类型比如DataSource、RedisTemplate、RestTemplate跑一次ctx.getBeansOfType(XXX.class)看看数量是不是 1。如果不是 1试着用AutoConfigureBefore或挪动自定义 bean 的注册时机把它压回 1 个再观察启动日志和连接数。

相关新闻

怎样在Windows上轻松搞定PDF处理?Poppler-Windows的完整实战指南

怎样在Windows上轻松搞定PDF处理?Poppler-Windows的完整实战指南

怎样在Windows上轻松搞定PDF处理?Poppler-Windows的完整实战指南 【免费下载链接】poppler-windows Download Poppler binaries packaged for Windows with dependencies 项目地址: https://gitcode.com/gh_mirrors/po/poppler-windows 还在为Windows系统处理…

2026/8/3 17:01:50 阅读更多 →
百考通AI充分考量:开题一键生成,让学术研究起步更从容,覆盖全场景需求

百考通AI充分考量:开题一键生成,让学术研究起步更从容,覆盖全场景需求

开题报告是学术写作的第一步,也是决定论文方向与质量的关键环节。从选题定题到框架搭建,从梳理研究背景到规划研究方法,繁琐的流程常常让专科、本科及研究生们倍感压力。百考通AI(https://www.baikaotongai.com)凭借智…

2026/8/3 17:00:50 阅读更多 →
如何免费解锁Microsoft Office完整功能:Ohook终极激活指南

如何免费解锁Microsoft Office完整功能:Ohook终极激活指南

如何免费解锁Microsoft Office完整功能:Ohook终极激活指南 【免费下载链接】ohook An universal Office "activation" hook with main focus of enabling full functionality of subscription editions 项目地址: https://gitcode.com/gh_mirrors/oh/oh…

2026/8/3 17:00:50 阅读更多 →

最新新闻

PowerShell智能补全与预测配置指南:PSReadLine与CompletionPredictor实战

PowerShell智能补全与预测配置指南:PSReadLine与CompletionPredictor实战

1. 项目概述:为什么我们需要一个更聪明的PowerShell? 如果你每天都在和Windows打交道,无论是管理服务器、编写自动化脚本,还是处理日常文件,PowerShell绝对是你绕不开的工具。它比传统的CMD强大得多,但很多…

2026/8/3 21:15:16 阅读更多 →
使用Anaconda轻松安装PyMOL:告别依赖冲突,打造专属分子可视化环境

使用Anaconda轻松安装PyMOL:告别依赖冲突,打造专属分子可视化环境

1. 为什么PyMOL的安装值得你花时间? 如果你正在读这篇文章,大概率是生物、化学、药学或者材料科学领域的研究者或学生。你或许刚拿到一组蛋白质的PDB文件,或者合成了一种新的小分子,迫切需要一个工具来把它从抽象的原子坐标变成一…

2026/8/3 21:15:16 阅读更多 →
SongGeneration终极指南:如何用AI创作高品质音乐,腾讯开源音乐生成神器完整教程

SongGeneration终极指南:如何用AI创作高品质音乐,腾讯开源音乐生成神器完整教程

SongGeneration终极指南:如何用AI创作高品质音乐,腾讯开源音乐生成神器完整教程 【免费下载链接】SongGeneration 腾讯开源SongGeneration项目,基于LeVo架构实现高品质AI歌曲生成。它采用混合音轨与双轨并行建模技术,既能融合人声…

2026/8/3 21:15:16 阅读更多 →
绿色积分消费增值模式系统(现成案例)

绿色积分消费增值模式系统(现成案例)

绿色积分消费增值模式系统开发编辑:araolin(私域邦网络土土哥)绿色积分消费增值模式是一种将环保行为与消费激励相结合的创新系统,通过积分奖励机制促进可持续消费。以下是开发该系统的关键步骤:系统架构设计绿色积分系…

2026/8/3 21:15:16 阅读更多 →
PowerShell智能补全配置指南:从基础到IDE级体验

PowerShell智能补全配置指南:从基础到IDE级体验

1. 从“盲打”到“指哪打哪”:为什么我们需要PowerShell的智能补全 如果你用过Windows自带的传统CMD,或者Linux的Bash,再回来用默认配置的PowerShell,可能会觉得有点“原始”。尤其是在需要快速输入一长串命令、路径或者参数的时候…

2026/8/3 21:15:16 阅读更多 →
如何免费打造你的专属三国杀游戏?无名杀开源项目完全指南

如何免费打造你的专属三国杀游戏?无名杀开源项目完全指南

如何免费打造你的专属三国杀游戏?无名杀开源项目完全指南 【免费下载链接】noname 项目地址: https://gitcode.com/GitHub_Trending/no/noname 你是否厌倦了商业卡牌游戏的各种限制?想要一个真正属于你自己的三国杀游戏体验?无名杀开…

2026/8/3 21:14:16 阅读更多 →

日新闻

3个让你工作效率翻倍的Umi-OCR实战技巧:免费离线文字识别完全指南

3个让你工作效率翻倍的Umi-OCR实战技巧:免费离线文字识别完全指南

3个让你工作效率翻倍的Umi-OCR实战技巧:免费离线文字识别完全指南 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。…

2026/8/3 0:00:47 阅读更多 →
[具身智能-181]:PC+服务器+具身机器人:构建具身智能从仿真到量产的闭环迭代混合架构

[具身智能-181]:PC+服务器+具身机器人:构建具身智能从仿真到量产的闭环迭代混合架构

PC服务器具身机器人:构建具身智能从仿真到量产的闭环迭代混合架构一、前言:具身智能需要“混合算力闭环系统”传统人工智能依赖云端静态数据集训练,不具备物理交互能力,无法适应真实世界的不确定性。具身智能(Embodied…

2026/8/3 0:00:47 阅读更多 →
[具身智能-181]:大分布式通信模型对比:看懂为什么 DDS 是 ROS2 底层通信最优解

[具身智能-181]:大分布式通信模型对比:看懂为什么 DDS 是 ROS2 底层通信最优解

前言构建机器人、具身智能这类分布式实时系统,通信底座直接决定整套系统的实时性、容错性、组网能力。分布式领域长期存在 4 类经典通信架构:点对点模式、Broker 中间代理模式、广播模式、以数据为中心(DDS)模式。很多开发者疑惑&…

2026/8/3 0:00:47 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/3 4:58:13 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/3 1:53:31 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/3 4:36:35 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/3 13:07:03 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/3 5:19:38 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/3 8:27:36 阅读更多 →