当前位置: 首页 > news >正文

Spring Boot 3 多数据源改造全流程:Druid、HikariCP 与 dynamic-datasource 实战总结

项目背景

初始架构与现状

在早期阶段,项目数据库结构简单,仅需连接一个主库,Druid的单数据源方案完全能够满足业务需求。
最初采用的是Spring Boot 3 + Druid 单数据源架构。

新需求的出现

随着业务的不断发展,项目逐渐暴露出以下痛点和新需求:

读写分离:部分业务场景对数据库读写压力较大,需要引入主从库,实现读写分离,提升系统性能和可用性。

多库动态切换:随着业务线扩展,部分功能需要访问不同的数据库,手动切换数据源变得繁琐且易出错。

Spring Boot 3 升级:项目升级到Spring Boot 3后,Druid部分版本兼容性不佳,且Spring官方推荐使用HikariCP作为默认连接池。

改造目标

基于上述背景,我们决定对原有的数据源架构进行升级,目标如下:
支持多数据源动态切换,满足主从库、分库等多场景需求。
简化数据源管理,减少手动切换和维护成本,提升开发效率。
兼容Spring Boot 3,采用官方推荐的HikariCP连接池,提升性能和稳定性。

技术选型

经过调研和对比,最终选定了 dynamic-datasource 作为多数据源动态切换的核心组件,配合Spring Boot 3默认的HikariCP连接池,实现多数据源的自动注册与灵活切换。

依赖选择、依赖分析与配置分析

依赖选择

原有依赖(Druid)

在改造前,项目依赖如下:

<!-- Druid 连接池(Spring Boot 3不再推荐) --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.24</version></dependency>

改造后依赖(HikariCP + dynamic-datasource)

步骤:

  • 去掉 Druid 相关依赖,避免与 HikariCP 或 dynamic-datasource 冲突。
  • 无需手动引入 HikariCP,Spring Boot 3 默认集成。
  • 引入 dynamic-datasource,实现多数据源动态切换。
<!-- dynamic-datasource 多数据源 springboot3版本 -->
<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot3-starter</artifactId><version>4.3.1</version>
</dependency>
<!-- HikariCP 由Spring Boot 3自动引入,无需单独声明 -->

依赖参考

迁移附加步骤

  • 彻底移除 Druid 相关依赖,包括druid-spring-boot-starterdruid本体,避免类冲突和自动装配干扰。
  • 删除或注释掉 Druid 相关的配置项,如spring.datasource.druid.*、监控Servlet等。
  • 检查代码中是否有 Druid 特有的API 或监控功能,如有需要用HikariCP或第三方监控方案替代。
  • 确认配置文件中的spring.datasource.typecom.zaxxer.hikari.HikariDataSource(可省略,Spring Boot 3默认即为HikariCP)。

连接池差异对比

对比项HikariCPDruid
性能极高,连接获取速度快,延迟低性能较好,但在高并发下略逊于HikariCP
内存占用低,轻量级相对较高
功能专注于连接池本身,功能精简功能丰富,支持SQL监控、Web界面等
配置复杂度简单,参数少,易于上手参数多,功能多,配置相对复杂
社区活跃度国外主流,Spring官方推荐国内主流,阿里维护,社区活跃
Spring Boot集成2.x/3.x默认连接池,无需额外依赖需单独引入依赖,Spring Boot 3兼容性需注意
监控能力基本的JMX监控内置强大的SQL、连接池监控
稳定性非常高,广泛用于高并发场景也很高,适合对监控有需求的场景

配置示例

多数据源配置示例(application-mysql.yaml):

spring:datasource:type: com.zaxxer.hikari.HikariDataSourcedynamic:primary: masterstrict: truedatasource:master:url: jdbc:mysql://xxx:3306/db1username: rootpassword: xxxslave:url: jdbc:mysql://xxx:3306/db2username: rootpassword: xxxhikari:maxPoolSize: 20minIdle: 10

-所有连接池参数统一写在hikari下。

  • dynamic-datasource会自动识别并注册所有配置的数据源,无需手动管理。

配置改造后遇到的问题

配置改造后遇到的问题

现象描述

  • 配置好 dynamic-datasource 后,项目启动时报错/无法读取多数据源配置
  • 具体报错信息:
    • 例如:No qualifying bean of type 'javax.sql.DataSource' available
    • 或者:dynamic-datasource未生效,始终只用一个数据源
    • 或者:com.zaxxer.hikari.HikariConfig 1031 - HikariPool-1 - dataSource or dataSourceClassName or jdbcUrl is required.

排查思路

  1. 确认依赖版本:dynamic-datasource 4.3.1,Spring Boot 3.x,版本兼容无误。

  2. 检查配置文件:格式、缩进、profile激活均正确。

  3. 排查代码数据库连接

    • 发现项目早期代码中自定义了DataSource的@Bean,如下:
@Configuration
@Primary
public class DataBaseConfig {@Bean("master")@Primary@ConfigurationProperties("spring.datasource")public DataSource dataSource() {.......}
}@Configuration
public class JdbcTemplateConfig {@Beanpublic JdbcTemplate jdbcTemplate(@Qualifier("master") DataSource dataSource) {return new JdbcTemplate(dataSource);}
}
  1. 查阅dynamic-datasource官方文档,发现其自动装配机制依赖于Spring Boot的自动注册,如果手动注册了同类型的Bean,会导致自动装配失效。

结论与原理分析

Spring Boot自动装配与手动@Bean的关系

Spring Boot会先执行自动装配(如dynamic-datasource的多数据源注册),再加载你手动写的@Bean。

如果你手动注册了同类型的Bean(如DataSource),你的手动Bean会覆盖自动装配的Bean,最终Spring容器只会保留你手动的那个。

@Primary注解会让Spring在有多个同类型Bean时,优先注入被标记的那个。

问题本质

自定义的DataSource和JdbcTemplate Bean覆盖了dynamic-datasource的自动装配,导致多数据源配置失效。
dynamic-datasource的自动注册被“顶掉”,只剩下你手动注册的那个数据源,主从切换、动态路由等功能全部失效。

解决方案与建议

删除或注释掉所有自定义的DataSource和JdbcTemplate Bean配置类。

只保留dynamic-datasource的配置文件,交给dynamic-datasource自动装配。

需要用JdbcTemplate时,直接@Autowired注入即可,无需指定数据源,dynamic-datasource会自动注入主数据源。

如需切换数据源,使用dynamic-datasource提供的@DS注解即可。

总结

用dynamic-datasource时,不要手动写DataSource和JdbcTemplate的@Bean,一切交给自动装配。

遇到多数据源无效、配置不生效时,优先排查是否有自定义DataSource相关Bean。

Spring Boot3推荐使用HikariCP,Druid已不再是首选。

http://www.lryc.cn/news/576569.html

相关文章:

  • 内网横向-工作流
  • 典型工程应用三
  • [rootme:ctf all the day]Ubuntu 8.04week wp
  • python 项目利用uv管理python包依赖
  • phpstudy 可以按照mysql 数据库
  • cf 禁止http/1.0和http/1.1的访问 是否会更安全?
  • 《自动控制原理 》- 第 1 章 自动控制的基本原理与方式
  • Confluence-测试用例执行规范
  • srs-gb28181 与 SRS 5.0 对 GB28181 国标支持
  • Learning to Prompt for Continual Learning
  • python基础21(2025.6.28)_全栈爬取_车168以及诗词名句案例
  • AUTOSAR图解==>AUTOSAR_AP_EXP_SOVD
  • Linux快速查找文件
  • JVM 之双亲委派机制与打破双亲委派
  • 【安卓Sensor框架-2】应用注册Sensor 流程
  • Everything
  • 深入解析 Electron 核心模块:构建跨平台桌面应用的关键
  • day45 Tensor board使用介绍
  • 【Bluedroid】蓝牙启动之BTM_reset_complete源码解析
  • 虚拟 DOM 与 Diff 算法
  • c++学习(五、函数高级)
  • 【AI智能体】Dify 核心组件从使用到实战操作详解
  • 设计模式-代理模式、装饰者模式
  • 【Java--SQL】${}与#{}区别和危害
  • git使用详解和示例
  • ByteMD+CozeAPI+Coze平台Agent+Next搭建AI辅助博客撰写平台(逻辑清楚,推荐!)
  • epitope3D: 精准预测蛋白表面的“抗原决定簇”
  • ABP VNext + 多数据库混合:SQL Server+PostgreSQL+MySQL
  • 【分布式机架感知】分布式机架感知能力的主流存储系统与数据库软件
  • 安卓应用启动页全版本兼容实战:从传统方案到Android 12+ SplashScreen API最佳实践