SpringBoot默认集成了HikariCP作为数据库连接池,它的速度快、轻量级,但在监控和SQL分析方面能力有限。Druid是阿里巴巴开源的数据库连接池,自带Web监控页面,可以实时查看SQL执行情况、慢查询、连接池状态等信息,排查线上问题非常方便。本文将完整讲解SpringBoot整合Druid的每一步操作,并把整合过程中常见的报错和解决方法一并梳理清楚。

一、引入Druid依赖的两种方式
整合Druid的第一步是引入依赖,这里有两种常见的做法。第一种是直接引入druid-spring-boot-starter,这种方式最简单,它会自动完成DataSource的装配,不需要手动写配置类。第二种是引入原生druid依赖,然后自己编写配置类来创建DruidDataSource。两种方式各有优劣,starter方式省事,原生方式控制力更强。
推荐使用starter方式,在pom.xml中添加如下依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.20</version>
</dependency>
</dependency>这里需要特别注意版本兼容问题。如果项目中使用的是SpringBoot 3.x,老版本的druid-spring-boot-starter(例如1.1.x)会因为javax.servlet包被移除而报错,必须使用1.2.x及以上版本。这也是很多开发者升级SpringBoot后突然发现Druid监控页面打不开的根本原因。另外要检查依赖树,确认spring-boot-starter-jdbc或mybatis等依赖已经引入,否则Druid没有用武之地。
二、application.yml核心配置详解
依赖引入之后,接下来在application.yml中编写配置。Druid的配置项比较多,但最关键的是把spring.datasource.type指定为DruidDataSource,这样SpringBoot才会用Druid替换默认的HikariCP。下面是一份比较完整的配置模板:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: 123456
druid:
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
validation-query: SELECT 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
filters: stat,wall,slf4j
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: "*.js,*.css,*.gif,*.jpg,*.png,/druid/*"
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: admin
login-password: admin123
allow: 127.0.0.1
reset-enable: false几个核心参数需要理解清楚。initial-size表示初始化时建立的连接数,max-active是最大活跃连接数,max-wait是获取连接的最大等待时间(毫秒),超时会抛出异常。validation-query建议使用SELECT 1,它是用来检测连接是否有效的探针语句。filters中的stat开启SQL监控统计,wall是防火墙防护,可以防SQL注入,slf4j则把日志输出交给日志框架管理。
web-stat-filter和stat-view-servlet是开启监控页面的关键配置。前者负责拦截请求并记录Web请求与Session的关联信息,后者提供监控页面的访问入口。配置完成后启动项目,访问http://127.0.0.1:8080/druid/,输入配置的用户名密码即可看到监控大屏,里面包含数据源、SQL监控、SQL防火墙、Web应用等标签页,功能相当丰富。
如果是生产环境,强烈建议不要把allow设置成空或者随意放开。allow参数用于IP白名单控制,留空表示允许所有IP访问,这在公网环境下存在安全风险。同时登录密码也不要使用弱密码,监控页面可以看到完整的SQL语句和URL信息,一旦泄露后果不小。
三、使用配置类方式整合(原生依赖)
如果不想使用starter,或者需要对数据源做更多定制,可以引入原生druid依赖并手动编写配置类。这种方式虽然代码量多一点,但可以清晰地看到每一个属性的注入过程,也方便排查配置不生效的问题。
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
Map<String, String> initParams = new HashMap<>();
initParams.put("loginUsername", "admin");
initParams.put("loginPassword", "admin123");
initParams.put("allow", "127.0.0.1");
bean.setInitParameters(initParams);
return bean;
}
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
bean.addUrlPatterns("/*");
Map<String, String> initParams = new HashMap<>();
initParams.put("exclusions", "*.js,*.css,*.gif,*.jpg,*.png,/druid/*");
bean.setInitParameters(initParams);
return bean;
}
}这段代码中,@ConfigurationProperties注解会把yml中spring.datasource前缀的属性批量绑定到DruidDataSource上,注意此时yml中的属性要直接写在spring.datasource下面,而不是spring.datasource.druid下面,写错层级是配置不生效的高频原因。另外在SpringBoot 3.x中,StatViewServlet所在的包已经从javax.servlet改为jakarta.servlet,import时千万别引错包,否则启动时会直接抛出ClassNotFoundError。
四、数据库密码加密配置
明文密码写在配置文件里存在泄露风险,Druid内置了ConfigFilter工具可以方便地对密码进行加密。首先在命令行执行加密命令生成密文:
java -cp druid-1.2.20.jar com.alibaba.druid.filter.config.ConfigTools your_password
执行后会输出privateKey、publicKey和password三段内容,把password和publicKey记录下来,然后在yml中这样配置:
spring:
datasource:
druid:
filters: config
connection-properties: config.decrypt=true;config.decrypt.key=${PUBLIC_KEY}
password: 加密后的密文原理是ConfigFilter在建立连接时用公钥解密密文,再传给数据库。需要注意的是,使用了config过滤器后,原来的stat等过滤器要一并写上,多个filter用逗号分隔,否则监控功能会丢失。公钥可以直接写在connection-properties中,也可以通过环境变量注入,生产环境更推荐后者,避免密钥硬编码在代码仓库里。
五、常见错误与解决方法
错误一:监控页面404。这是整合Druid时出现频率最高的问题。排查顺序一般是:先确认druid-spring-boot-starter依赖是否正确引入;再检查stat-view-servlet的enabled是否为true;然后看项目是否集成了SpringSecurity或自定义了拦截器,把/druid/路径拦截了,这种情况需要在安全配置中放行该路径;最后检查是否有自定义的ServletRegistrationBean冲突。如果项目使用了context-path,访问地址要加上前缀,例如http://127.0.0.1:8080/api/druid/。
错误二:配置不生效,实际还是HikariCP。现象是启动日志里打印的DataSource类型不是DruidDataSource。常见原因有两个:一是yml中漏掉了type配置;二是同时引入了HikariCP且它的优先级更高。可以在启动后通过日志或断点确认DataSource的实际类型,也可以在测试类中注入DataSource并打印其类名来验证。
错误三:wait_timeout连接超时断开。MySQL默认的wait_timeout是8小时,连接闲置超过这个时间会被服务端主动断开,而连接池并不知道,下次取用就会报Connection is not available。解决办法就是前面配置中的test-while-idle配合validation-query,让池子在空闲时定期校验连接有效性,同时建议开启keep-alive参数。
错误四:Statement被关闭报错。如果开启了pool-prepared-statements,要注意某些数据库或中间件(比如达梦、某些分库分表组件)对PSCache支持不好,可以尝试关闭该选项。另外max-pool-prepared-statement-per-connection-size在高并发场景建议适当调大,否则可能出现获取PreparedStatement等待超时的现象。
错误五:filter配置冲突导致启动失败。典型报错是提示filters中包含不存在的过滤器名称。filters配置项中的名字必须与Druid内置过滤器严格匹配,stat、wall、slf4j、config、log4j等,写错一个字母就会抛异常。如果同时通过代码的setFilters方法和yml配置了过滤器,还可能产生重复叠加的问题,保持单一配置来源是最稳妥的做法。
六、性能调优建议
连接池参数不是拍脑袋定的,要结合实际业务调整。max-active的估算可以参考公式:连接数 = 核心数 * 2 + 有效磁盘数,对于数据库来说一般单实例建议控制在20到50之间,设置过大会拖垮数据库,过小则会造成请求排队。max-wait建议设置一个合理值,比如5000到10000毫秒,快速失败比无限等待更有利于系统自保。
慢SQL监控是Drud的一大亮点,可以在yml中配置慢SQL日志输出:
spring:
datasource:
druid:
filter:
stat:
slow-sql-millis: 2000
log-slow-sql: true
merge-sql: trueslow-sql-millis定义慢SQL阈值,超过2秒的SQL会被记录到监控页面并输出日志,merge-sql可以把相似结构的SQL合并统计,避免监控列表被大量参数不同的同构SQL刷屏。建议上线初期开启这些监控观察一段时间,根据真实的SQL执行数据做针对性优化,这比凭感觉写代码有效得多。
总的来说,SpringBoot整合Druid的流程并不复杂,关键是理解每个配置项背后的含义,遇到问题时能够顺着DataSource的装配链路去排查。监控能力是Druid相对其他连接池最大的优势,用好它可以让线上问题排查事半功倍。
SpringBootDruid连接池数据库配置修改时间:2026-09-05 12:10:43