BladeX 多数据源配置踩坑:注释掉一个依赖就解决了?
文章目录前言一、问题现象1.1 在 IDEA 本地运行报错清晰1.2 在 Ubuntu 服务器上运行报错隐晦二、为什么 IDEA 能快速暴露问题2.1 IDEA 的 Maven 依赖冲突检测2.2 真实原因Spring Boot 的失败降级Failback三、解决方案非常简单3.1 错误做法手动添加 dynamic-datasource 依赖3.2 正确做法注释掉它四、经验总结给开发者的建议五、一句话总结总结前言最近在基于BladeX 4.8.0Spring Boot 3.5.9JDK 17的项目中配置多数据源MySQL Doris遇到一个非常诡异的问题在IDEA 本地运行启动时直接抛出类方法不存在的清晰异常几秒钟就定位到依赖冲突。把同一个代码包部署到Ubuntu 服务器启动报错却变成了java.sql.SQLException: connect error, url jdbc:h2:mem:...看起来像是数据库 URL 配错了完全想不到是依赖冲突。同样的代码不同的环境报错信息天差地别。这篇文章就记录下这个“幽灵问题”的排查过程以及为什么 IDEA 能帮你省下两小时。一、问题现象1.1 在 IDEA 本地运行报错清晰启动日志中出现An attempt was made to call a method that does not exist. The attempt was made from the following location: org.springblade.core.db.dynamic.config.DynamicDataSourceConfiguration.dynamicTransactionAdvisor(DynamicDataSourceConfiguration.java:109) The following method did not exist: void com.baomidou.dynamic.datasource.aop.DynamicLocalTransactionInterceptor.init(java.lang.Boolean)一眼就能看出是dynamic-datasource的版本冲突——BladeX 内置的旧版3.6.1与我手动引入的新版4.1.3在构造函数签名上不兼容。1.2 在 Ubuntu 服务器上运行报错隐晦同样的代码打包后部署到服务器日志变成了这样com.alibaba.druid.pool.DruidDataSource:init datasource error,url:jdbc:h2:mem:fd3e93d1-8d58-4383-a164-8e5006379ed4;DB_CLOSE_DELAY-1;DB_CLOSE_ON_EXITFALSEjava.sql.SQLException:connect error,url jdbc:h2:mem:...,driverClasscom.mysql.cj.jdbc.Driver错误信息指向H2 内存数据库和MySQL 驱动的不匹配完全看不出是依赖冲突。如果不了解 BladeX 内部机制可能会花大量时间去检查application.yml的配置、检查 H2 依赖、怀疑 Druid 配置错误——实际上这些都没问题。二、为什么 IDEA 能快速暴露问题2.1 IDEA 的 Maven 依赖冲突检测IDEA 在启动时会分析 classpath如果同一个类出现在多个 JAR 中且版本不同会在控制台输出Loaded from ...之类的信息。更重要的是当 Spring 容器实例化 Bean 时如果方法签名不匹配会立即抛出NoSuchMethodError并给出完整的调用链让你直接定位到哪个类调用了哪个方法。而在 Ubuntu 服务器上使用java -jar直接运行JVM 默认不会主动检测依赖冲突。只有当代码执行到具体冲突点时才会抛出异常。但尴尬的是BladeX 的DynamicDataSourceConfiguration在刷新容器时就会调用有问题的构造函数理论上也会抛出同样的异常。那为什么服务器上却变成了 H2 的错误2.2 真实原因Spring Boot 的失败降级Failback这是因为依赖冲突导致dynamic-datasource的自动配置完全失败相关 Bean 没有被注册。Spring Boot 发现没有动态数据源也没有配置标准的spring.datasource.url于是自动创建了一个嵌入式 H2 内存数据库作为默认数据源。但是你的项目中引入了 Druid 的 StarterDruid 试图接管这个 H2 数据源并使用你配置的driver-class-name: com.mysql.cj.jdbc.Driver去连接 H2 的 URL自然就报错了。所以服务器上的报错其实是连锁反应依赖冲突 → 多数据源配置失效 → Spring Boot 回退到 H2 → Druid 瞎搅和 → 抛出让人摸不着头脑的 SQLException。这个降级过程在服务器上静默发生没有打出明确的NoSuchMethodError可能被吞掉了或者被 Druid 的初始化异常覆盖了最终的异常信息。而 IDEA 因为更激进的类加载和更完整的堆栈打印直接把原始冲突抛了出来。三、解决方案非常简单3.1 错误做法手动添加dynamic-datasource依赖项目pom.xml中我写下了这样一段!-- ❌ 错误BladeX 已经内置了不要手动加 --dependencygroupIdcom.baomidou/groupIdartifactIddynamic-datasource-spring-boot-starter/artifactIdversion4.1.3/version/dependency3.2 正确做法注释掉它!-- ✅ 正确注释掉完全依赖 BladeX 自带的版本 --!-- dependency groupIdcom.baomidou/groupId artifactIddynamic-datasource-spring-boot-starter/artifactId version4.1.3/version /dependency --然后直接使用 BladeX 提供的多数据源能力配置文件照常写spring:datasource:dynamic:primary:collectdatasource:collect:url:jdbc:mysql://...username:xxxpassword:xxxdriver-class-name:com.mysql.cj.jdbc.Driverdoris-hd:url:jdbc:mysql://...username:xxxpassword:xxxdriver-class-name:com.mysql.cj.jdbc.Driver⚠️注意如果你之前为了“升级”而添加了dynamic-datasource-spring-boot3-starter实测它不会引起冲突因为包名/类名有变化但最稳妥的做法依然是不加任何多余的依赖。四、经验总结环境报错表现原因IDEA 本地NoSuchMethodError: DynamicLocalTransactionInterceptor.init(Boolean)IDE 的依赖检查 Spring 容器启动时立即抛出原始异常Ubuntu 服务器SQLException: connect error, url jdbc:h2:mem:...依赖冲突导致多数据源失效 → Spring Boot 回退 H2 → Druid 连接错误原始异常被掩盖给开发者的建议永远不要在 BladeX 中手动添加dynamic-datasource-spring-boot-starter。框架已经通过blade-starter-tenant-dynamic内置了。优先在本地 IDEA 中测试多数据源报错信息更直接能快速定位依赖冲突。如果服务器上报出 H2 相关的错误首怀疑多数据源配置没有生效检查是否有依赖冲突或spring.datasource.dynamic.enabled是否被关闭。可以在服务器启动脚本中添加-Dmaven.tomcat.debugtrue或使用mvn dependency:tree预先检查依赖树避免“盲人摸象”。五、一句话总结BladeX 自带多数据源不要重复造轮子。注释掉多余的依赖IDE 会感谢你服务器也会感谢你。如果你的服务器还在报 H2 错误不妨回到本地用 IDEA 跑一下——它会把真相直接甩在你脸上。总结如果此篇文章有帮助到您, 希望打大佬们能关注、点赞、收藏、评论支持一波非常感谢大家如果有不对的地方请指正!!!