踩坑实录!DynamicRoutingDataSource配置不加载,竟是IDEA编译搞的鬼 dynamic-datasource cannot find primary datasource
踩坑实录!DynamicRoutingDataSource配置不加载,竟是IDEA编译搞的鬼
前言
最近在做项目多数据源切换,选用了MyBatis-Plus生态的dynamic-datasource动态数据源组件,本以为是常规配置操作,结果直接启动报错:Caused by: java.lang.IllegalArgumentException: dynamic-datasource cannot find primary datasource。
顺着报错排查源码,发现更诡异的问题:配置文件明明完整编写了多数据源,且指定了primary主数据源,启动后DynamicRoutingDataSource依旧加载不到任何数据源,深入Debug后定位到createDataSourceMap方法中,dataSourcePropertiesMap集合完全为空。
更离谱的是,我一贯的操作都是Maven clean之后直接IDEA Debug启动,之前从未出过问题,这次偏偏栽了跟头!排查了依赖、配置格式、启动类排除项,折腾了大半天,最后发现根因居然和代码无关,全是IDEA编译打包的锅。今天把完整排坑过程、源码定位思路、解决方案整理出来,帮大家避开同款陷阱。
一、问题现象
-
引入dynamic-datasource依赖,按照官方文档编写yml多数据源配置,启动类排除默认数据源自动配置;
-
项目启动直接抛出异常:dynamic-datasource cannot find primary datasource,提示找不到主数据源,项目无法正常启动;
-
源码Debug定位:进入DynamicRoutingDataSource的createDataSourceMap方法,发现dataSourcePropertiesMap集合为空,配置文件里的数据源完全没加载;
-
诡异对比:
-
直接IDEA Debug启动:target/classes目录下无任何配置文件,读取不到yml;
-
执行Maven clean compile后启动:target目录生成配置文件,数据源正常加载。
-
二、常规排查全翻车(踩坑必经之路)
刚开始我完全没往编译打包方向想,按照常规多数据源不加载的思路逐一排查,结果全踩空了,给大家避个雷:
1. 依赖排查
确认引入了dynamic-datasource-spring-boot-starter核心依赖,未缺失、无版本冲突,排除了依赖导致的不加载。
2. 配置文件格式排查
反复核对yml缩进、配置层级,所有数据源配置都放在spring.datasource.dynamic.datasource下,无外置裸写url、username的情况,配置格式完全合规。
3. 启动类排除项排查
仅排除了DataSourceAutoConfiguration,未误排除动态数据源自动配置类,无自动配置冲突问题。
4. 源码断点排查
断点打在DynamicDataSourceAutoConfiguration、DynamicDataSourceProperties、afterPropertiesSet等核心位置,确认Spring加载了动态数据源Bean,但是配置绑定失败,读取到的数据源集合为空。
一轮排查下来,代码、配置、依赖全没问题,问题彻底陷入僵局,直到对比了两次启动的target目录,才发现突破口!
三、源码定位核心:为什么dataSourcePropertiesMap为空?
先给大家明确源码逻辑,方便理解根因:
-
DynamicDataSourceProperties负责读取spring.datasource.dynamic前缀的配置;
-
DynamicRoutingDataSource初始化时,会从properties中获取数据源集合,赋值给dataSourcePropertiesMap;
-
Spring读取配置文件,默认是从target/classes目录下读取,而非源码目录的resources。
dataSourcePropertiesMap为空 → 框架读取不到任何数据源配置 → 自然找不到指定的primary主数据源 → 抛出 cannot find primary datasource 异常,并不是配置里没加primary字段,而是Spring压根没读到配置文件!
四、终极根因:IDEA编译不复制resources资源文件
先给大家讲清楚两种启动方式的区别:
1. Maven clean compile 启动(正常)
执行Maven编译命令,会自动触发Maven生命周期中的process-resources阶段,自动将src/main/resources下的所有配置文件、资源文件,复制到target/classes目录下,Spring能正常读取配置,数据源自然加载成功。
2. IDEA直接Debug启动(异常)
直接点击IDEA的Debug Application启动,默认不会触发Maven资源拷贝流程,仅仅编译Java源码,不处理resources资源文件,导致target/classes目录下没有yml、properties配置文件,Spring无配置可读取,数据源加载为空。
3. 为啥之前没问题,现在突然翻车?
很多同学和我一样,常年clean+直接启动,从没出过问题,突然异常无非这几个原因:
-
IDEA版本更新、缓存损坏,构建逻辑被重置;
-
src/main/resources目录丢失【资源目录标记】;
-
IDEA构建委托配置被修改,未交给Maven处理。
五、一站式解决方案(永久生效)
方案一:标记Resources资源目录(基础修复)
-
快捷键Ctrl+Alt+Shift+S打开Project Structure;
-
选中当前模块,点击Sources选项卡;
-
找到src/main/resources目录,右键标记为Resources;
-
点击应用,重启项目即可。
方案二:IDEA运行配置添加Maven前置命令(一劳永逸)
-
打开Run/Debug Configurations,找到项目启动类;
-
找到Before launch选项,点击+号,选择Add Maven Goal;
-
输入命令:process-resources compile;
-
保存配置,后续直接启动,会自动先拷贝资源再编译。
方案三:委托IDEA构建给Maven(最稳)
-
打开File-Settings,搜索Build Tools - Maven;
-
勾选【Delegate IDE build/run actions to Maven】;
-
清理缓存重启(File-Invalidate Caches),彻底解决资源不复制问题。
六、避坑总结
-
遇到 dynamic-datasource cannot find primary datasource 报错,别先急着加primary配置、改数据源名称,优先查看target/classes目录下有没有配置文件;
-
SpringBoot项目读取配置,默认依赖target编译后的文件,而非源码resources;
-
IDEA直接启动≠Maven完整编译,资源文件拷贝需要手动配置;
-
非常规代码问题,优先排查工具配置、编译打包、目录标记问题,少走弯路。
结尾
这次排查真的是细节打败一切,看似是多数据源配置问题,实则是IDEA编译的小坑,折腾了不少时间。把这篇踩坑实录分享出来,希望大家遇到同款问题时,能快速定位根因,不用再做无用功。
如果这篇文章对你有帮助,欢迎点赞+收藏+关注,后续会持续分享Java开发实战踩坑、源码解析干货,大家有同款问题也可以评论区交流~
(注:文档部分内容可能由 AI 生成)
更多推荐
所有评论(0)