Spring Boot 3集成Druid踩坑指南:四大报错与配置模板

发布时间:2026/9/13 4:30:28
Spring Boot 3集成Druid踩坑指南:四大报错与配置模板 Spring Boot 3正式版发布之后我手上的老项目一直在评估升级。项目原来跑在Spring Boot 2.7上数据库连接池一直用Druid工具链也都围着Druid的监控体系转。本以为升级到Spring Boot 3最多改改依赖版本结果实际操作下来差点被劝退javax.servlet找不到、循环依赖起不来、监控页面404、配置参数全部不生效……零零散散的坑加起来足足折腾了两三天才把整套环境理顺。这篇就把Spring Boot 3集成Druid过程中真正会踩的坑、报错原文、解决方式全部记录下来同时把最终能直接用的配置模板也一并放出来。无论是正在做Spring Boot 3迁移的老项目还是打算新项目直接上Boot 3加Druid的同事这篇文章应该能帮你少走几圈弯路。1. 先搞清楚这个Druid到底是谁1.1 项目升级背景与问题全景老项目的技术栈比较常规Spring Boot 2.7.18、JDK8、MySQL 8、MyBatis-Plus连接池用的是阿里巴巴Druid对应的Maven依赖是druid-spring-boot-starter版本一直锁在1.2.6。整体运行了一年多Druid的监控页面、慢SQL记录、防火墙功能都用得比较顺。升级目标定的是Spring Boot 3.2.x加JDK17Druid这边我提前看了一眼发现官方从1.2.18开始推出了druid-spring-boot-3-starter专门适配Spring Boot 3于是就把版本提到1.2.20。本来以为换个坐标就行结果启动时连续出现四类问题java.lang.ClassNotFoundException: javax.servlet.FilterBeanCurrentlyInCreationException应用上下文循环依赖直接启动失败Failed to configure a DataSource: url attribute is not specifiedDruid监控页面404/druid/index.html怎么访问都是白屏这些问题单独看任何一个都不算复杂但它们会连环触发。比如javax问题没解决后面循环依赖和url不识别都会跟着一起来。所以排查时必须按顺序来不能看到报错就盲目改配置。1.2 两个容易被忽略的前提先说第一个容易混淆的点连接池Druid和数据库Apache Druid是两码事。每次在社区搜“Druid性能对比”搜出来的大都是Apache Druid和StarRocks、ClickHouse这类OLAP数据库的对比不少人因此看懵了。本文说的Druid是阿里巴巴开源的数据库连接池组件负责管理JDBC连接、连接监控、SQL防火墙跟OLAP数据库完全不是一类东西。这块概念先理清楚后面搜索问题时才知道该往哪个方向查。第二个前提是Spring Boot 3把Java EE的包名从javax.*整体迁移到了jakarta.*。以Servlet为例原来的javax.servlet.Filter变成了jakarta.servlet.Filterjavax.servlet.http.HttpServlet变成了jakarta.servlet.http.HttpServlet。Spring Framework 6和Spring Boot 3内部全部基于Jakarta EE 9展开老版本的Druid starter内部编译时依赖的还是javax包到了新的类加载环境下就找不到类了。这是大多数老连接池组件不兼容Boot 3的根源理解了这一点后面就能解释为什么必须换starter。2. 环境准备与技术选型别再用旧版starter了2.1 JDK和Spring Boot版本选择Spring Boot 3强制要求JDK17及以上所以升级前先把JDK切到17或者21。我这次用的是JDK17原因很实际JDK21虽然也是LTS但项目里部分第三方库的字节码增强、反射操作在21上偶尔会有兼容提醒而JDK17是目前Spring Boot 3.x社区验证最广泛的运行环境。创建项目时IDEA里直接用Spring Initializr选Spring Boot 3.2.x、Java 17就行。这里有个细节IDEA默认的Spring Initializr如果网络不畅会很慢甚至拉不到依赖建议改用自己的Maven镜像或者在IDEA里设置自定义Initializr地址。我习惯直接建一个空的Maven项目然后手动维护pom.xml这样哪个依赖升级了、哪个版本有不兼容心里都有数。Spring Boot次版本的选择也有讲究。3.0.x是过渡版本很多组件当时适配还不到位3.1.x比较稳定但对新特性的支持少一些3.2.x是目前最主流的稳定线AOT编译、虚拟线程等特性都有不错的表现。Druid从1.2.18开始支持Boot 3我自己用下来1.2.20这个版本在3.2.x上表现最稳1.2.18和1.2.19在某些场景下还有过滤器和配置绑定的零碎问题。2.2 Maven依赖的正确姿势升级最核心的一步就是把旧依赖替换掉!-- 错误示例这个坐标是给Spring Boot 2.x用的 -- !-- dependency groupIdcom.alibaba/groupId artifactIddruid-spring-boot-starter/artifactId version1.2.6/version /dependency -- !-- 正确示例Spring Boot 3专用starter -- dependency groupIdcom.alibaba/groupId artifactIddruid-spring-boot-3-starter/artifactId version1.2.20/version /dependency注意druid-spring-boot-3-starter内部会传递依赖Druid核心包版本一般和starter保持一致不需要额外再显式引进一个druid依赖。如果你在pom里同时看到druid和druid-spring-boot-starter一定要检查是否混用了两个不同代际的坐标这是很多冲突的源头。除了Druid之外还有几个配套依赖需要同步调整。MySQL 8的驱动从mysql-connector-java改成了mysql-connector-j坐标里的groupId也变了MyBatis-Plus官方从3.5.3开始单独提供mybatis-plus-spring-boot3-starter配Boot 3必须用它而不是老的mybatis-plus-boot-starter。这些细节单独看都不起眼但组合在一起就是Spring Boot 3升级瞬间从“换个版本号”变成“连环踩坑”的原因。2.3 为什么Spring Boot 3会让老版Druid直接废掉很多时候我们排错只看到了表面的ClassNotFoundException没意识到它背后是整个Java EE命名空间的迁移。Spring Boot 3基于Spring Framework 6Spring Framework 6基于Jakarta EE 9规范Servlet API由javax.servlet变成jakarta.servlet。Druid的starter内部要加载com.alibaba.druid.support.http.stat.StatViewServlet等类这些类在编译和运行时要依赖Servlet API老版本底层绑定的是javax放在Spring Boot 3环境里类加载器自然找不到。这不是单纯升级一个依赖版本就能跳过的问题必须使用官方重新适配过的druid-spring-boot-3-starter。从Druid 1.2.18开始官方同时维护两个分支的starter一个继续服务Boot 2一个专供Boot 3。使用新分支之后内部的Servlet组件、自动配置类都会引用jakarta包和Spring Boot 3的类加载机制才能对上。3. 核心踩坑实战四个报错的完整修复过程3.1 报错一java.lang.ClassNotFoundException: javax.servlet.Filter报错日志最典型的一段长这样Caused by: java.lang.NoClassDefFoundError: javax/servlet/Filter at java.base/java.lang.ClassLoader.defineClass1(Native Method) ... Caused by: java.lang.ClassNotFoundException: javax.servlet.Filter这个报错出现的位置通常在Druid启动时初始化过滤器或者Tomcat容器装配Web组件时。原因很明确项目classpath里没有javax.servlet.Filter这个类因为Spring Boot 3内嵌的Tomcat 10已经完全基于Jakarta Servlet。解决方案就是把pom里的Druid依赖替换成druid-spring-boot-3-starter。但如果替换之后仍然报错就要检查项目里是否存在其他遗留的Servlet依赖比如老版本的servlet-api、javax.servlet.jsp-api或者某些第三方包内部传递依赖了javax.servlet。我遇到过一种情况某个内部工具包在pom里显式引了javax.servlet-api:4.0.1结果Druid升级后依然报类找不到。这种就得在该工具包的依赖声明里排除掉javax.servlet-api或者用mvn dependency:tree查一下冲突来源。实操时建议先跑一下mvn dependency:tree -Dincludesjavax.servlet,jakarta.servlet把依赖树里所有javax.servlet相关的包找出来逐个判断是哪些组件带进来的。能排除就排除不能排除就需要评估该组件是否兼容Boot 3。3.2 报错二BeanCurrentlyInCreationException循环依赖直接启动失败升级过程中第二个拦路虎是启动报一堆循环依赖日志中间有一段类似The dependencies of some of the beans in the application context form a cycle: ┌─────┐ | druidDataSource (field private ...) └─────┘Spring Boot 2.6之后默认把spring.main.allow-circular-references设为falseSpring Boot 3延续了这个策略一旦出现循环依赖就直接拒绝启动。而老项目里为了让Druid和一些基础配置共享数据源信息以前写了不少“绕圈子”的Bean依赖在Boot 2.6之前其实也能跑升级之后就原形毕露了。出现这个报错后网上最常见的建议是spring: main: allow-circular-references: true这个配置的确能让项目先跑起来但我强烈不建议一上来就加。循环依赖一旦放开Spring IoC容器会以“三段式缓存”方式提前暴露Bean这种模式在AOP代理、事务切面生效时很容易导致代理对象和原始对象不一致出现事务不生效、切面只执行一次的诡异问题。正确的处理思路是找到循环依赖的起源点。我的项目中循环依赖大的源头就是我自己的DruidConfig配置类我手动声明了DruidDataSource的Bean同时又在另一个配置类里注入了这个DataSource来构建JdbcTemplate而Druid的自动配置类也在初始化DataSource多个配置路径互相引用就形成了环。解决方式有两种一是完全走Druid starter的自动配置不自己写DruidDataSource的Bean。当你在配置里写spring.datasource.url、spring.datasource.druid.url时starter会自动声明好数据源你只需要在配置类里用Autowired或者构造器注入DataSource即可。这种方式最省心也是官方推荐用法。二是如果项目必须自定义DataSource那就需要显式使用ConfigurationProperties(prefix spring.datasource.druid)绑定参数然后在创建Bean时把循环依赖的来源拆掉。比如JdbcTemplate不要直接注入自定义DruidDataSource而是改注入DataSource接口类型让Spring在容器中自动寻找合适的实现。3.3 报错三Failed to configure a DataSource: url attribute is not specified这个报错很经典Spring Boot给出的提示是Description: Failed to configure a DataSource: url attribute is not specified and no embedded datasource could be configured. Reason: Failed to determine a suitable driver class在我这次升级场景里出现的原因不是没写url而是配置路径没对上。老项目里原来用的是spring.datasource.url同时还在pom里通过spring.datasource.type指定了com.alibaba.druid.pool.DruidDataSource。到了Boot 3Druid starter的自动配置读取的是spring.datasource.druid.*前缀和Boot默认的spring.datasource.*前缀两者叠加很容易造成数据源类型被识别成Hikari或者空白导致url参数没有被正确带入。处理办法是统一配置前缀。如果用了druid-spring-boot-3-starter最稳妥的写法是spring: datasource: druid: url: jdbc:mysql://localhost:3306/app_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver注意driver-class-name在Druid starter里也可以写到spring.datasource.druid.driver-class-name下。如果同时保留spring.datasource.url和spring.datasource.druid.url可能有版本差异导致优先级不可控建议去掉前者只保留后者。另外还有一种情况是代码里手动new DruidDataSource()然后不设url。这种情况多见于网上零散示例代码把配置写死在Java类里。升级到Boot 3后建议一律改成配置文件绑定方便统一管理。3.4 报错四Druid监控页面404数据源正常跑起来了下一步就是看监控页。默认访问http://localhost:8080/druid/index.html结果404页面资源根本找不到。这个问题的原因分两层第一层是druid-spring-boot-3-starter和老的druid-spring-boot-starter不同监控页面默认是关闭的必须显式打开stat-view-servlet。第二层是即使开了如果项目里同时引入了其他Web组件比如knife4j、Spring Security也没法直接访问。我升级的第二个阶段就遇到knife4j和Druid监控的路径冲突knife4j会把所有/doc.html相关资源路径拦截下来虽然不影响Druid的JSON接口但Druid监控页面的静态资源一直被重定向页面白屏。正确的配置如下spring: datasource: druid: stat-view-servlet: enabled: true url-pattern: /druid/* login-username: admin login-password: admin123 allow: 127.0.0.1 deny: web-stat-filter: enabled: true url-pattern: /* exclusions: /druid/*,*.js,*.css,*.gif,*.jpg,*.png,*.ico这里要特别提醒两点login-username和login-password一定要设不要用默认的空密码。这个页面暴露了所有SQL执行记录和慢SQL明细裸奔在公网上等于把数据库内部结构展示给别人。allow和deny的白名单配置要注意格式是IP字符串多个用逗号分隔。如果配了deny有值且和allow有交集deny优先级更高。如果开了之后还是404先排查是不是路径写错了再用浏览器开发者工具看控制台是HTML请求404还是静态资源404。如果是静态资源404大概率是web-stat-filter的exclusions配置把CSS、JS文件过滤掉了补充一下扩展名就行。4. 最终可直接复用的配置模板4.1 pom.xml完整依赖清单把上面几个坑都踩平之后我整理出了下面这套可复现的依赖清单。它适用于Spring Boot 3.2.x JDK17 MySQL 8 MyBatis-Plus Druid如果项目里不用MyBatis-Plus把对应坐标删掉即可。properties java.version17/java.version spring-boot.version3.2.5/spring-boot.version druid.version1.2.20/druid.version mybatis-plus.version3.5.5/mybatis-plus.version knife4j.version4.4.0/knife4j.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-jdbc/artifactId /dependency dependency groupIdcom.alibaba/groupId artifactIddruid-spring-boot-3-starter/artifactId version${druid.version}/version /dependency dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-spring-boot3-starter/artifactId version${mybatis-plus.version}/version /dependency dependency groupIdcom.github.xiaoymin/groupId artifactIdknife4j-openapi3-jakarta-spring-boot-starter/artifactId version${knife4j.version}/version /dependency /dependencies几个容易踩的版本联动点再强调一次druid-spring-boot-3-starter最低是1.2.18但1.2.20更稳1.2.23之后又合入过一些监控页面相关的修复可以按需升级。mysql-connector-j是MySQL官方新坐标千万别再用mysql-connector-java。MyBatis-Plus必须用mybatis-plus-spring-boot3-starter否则会有SessionFactory初始化失败的问题。knife4j直接用适配Jakarta的knife4j-openapi3-jakarta-spring-boot-starter版本选4.4.0以上。4.2 application.yml完整配置与参数解释下面是我最终上线使用的配置参数偏向生产环境注释里写了每个参数的作用和取舍原因。spring: datasource: druid: url: jdbc:mysql://localhost:3306/app_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver # 初始化连接数项目启动时立即建立的连接数推荐与min-idle一致 initial-size: 5 # 最小空闲连接数低于这个值会触发连接创建 min-idle: 5 # 最大活跃连接数并发超过这个值多余请求会排队等待 max-active: 20 # 获取连接的最大等待时间毫秒超过则抛出异常避免线程无限阻塞 max-wait: 60000 # 检测空闲连接的间隔单位毫秒 time-between-eviction-runs-millis: 60000 # 连接在池中最小空闲时间超过才可能被回收 min-evictable-idle-time-millis: 300000 # 检测连接是否可用的SQLMySQL用select 1Oracle用select 1 from dual validation-query: SELECT 1 # 获取连接时是否检测有效性推荐false配合test-while-idle更高效 test-while-idle: true test-on-borrow: false test-on-return: false # 是否缓存PreparedStatementPSCache对MySQL性能提升有限但能降低CPU pool-prepared-statements: true max-pool-prepared-statement-per-connection-size: 20 # 配置监控统计拦截的filtersstat是监控统计wall是SQL防火墙log4j2是日志输出 filters: stat,wall,slf4j # 通过connectProperties属性来打开mergeSql和慢SQL记录 connection-properties: druid.stat.mergeSqltrue;druid.stat.slowSqlMillis2000 # 监控页面 stat-view-servlet: enabled: true url-pattern: /druid/* login-username: admin login-password: admin123 allow: 127.0.0.1 deny: # Web应用监控过滤器 web-stat-filter: enabled: true url-pattern: /* exclusions: /druid/*,*.js,*.css,*.gif,*.jpg,*.png,*.ico # 防火墙Wall Filter单独配置防止SQL注入 wall: enabled: true config: multi-statement-allow: false none-base-statement-allow: false解释几个容易忽略的点max-wait建议设置不设的话高并发下获取不到连接会快速失败或一直卡住设了之后虽然会抛异常但至少能及时暴露问题。test-while-idle配合time-between-eviction-runs-millis是最常见的连接可用性检测方式不建议再把test-on-borrow打开每次取连接都执行SELECT 1在高QPS场景下白白增加数据库负担。filters里的stat必须写在最前面否则监控数据统计不到wall是SQL防火墙一般建议生产开启但如果你有大量多条SQL一次提交的需求multi-statement-allow要谨慎打开否则会被判断为非法语句直接拦截。4.3 DruidConfig配置类写法注意别重复注册使用druid-spring-boot-3-starter之后理论上不需要手动声明DruidDataSource。但很多老项目确实喜欢自己创建一个配置类方便动态添加过滤器或对数据源做额外处理。这里给出一版不会和自动配置冲突的写法Configuration Slf4j public class DruidConfig { /** * 手动声明数据源完全接管Druid的初始化。 * 注意前缀必须是spring.datasource.druid否则yml里的连接池参数绑定不上。 */ Bean ConfigurationProperties(prefix spring.datasource.druid) public DruidDataSource druidDataSource() { DruidDataSource dataSource new DruidDataSource(); // 这里不需要再手动setUrl等ConfigurationProperties会自动绑定 return dataSource; } /** * 配置监控页面Servlet。 * 如果已经在yml里配置了stat-view-servlet.enabledtrue这个Bean可能重复注册二选一即可。 */ Bean public ServletRegistrationBeanStatViewServlet statViewServlet() { StatViewServlet servlet new StatViewServlet(); ServletRegistrationBeanStatViewServlet bean new ServletRegistrationBean(servlet, /druid/*); bean.addInitParameter(loginUsername, admin); bean.addInitParameter(loginPassword, admin123); bean.addInitParameter(allow, 127.0.0.1); return bean; } /** * 配置Web监控过滤器统计请求对应的SQL执行情况。 */ Bean public FilterRegistrationBeanWebStatFilter webStatFilter() { WebStatFilter filter new WebStatFilter(); FilterRegistrationBeanWebStatFilter bean new FilterRegistrationBean(); bean.setFilter(filter); bean.addUrlPatterns(/*); bean.addInitParameter(exclusions, /druid/*,*.js,*.css,*.gif,*.jpg,*.png,*.ico); return bean; } }这里有几点务必要注意手动声明DruidDataSource之后yml里如果同时也设置了spring.datasource.druid.stat-view-servlet.enabledtrue相当于监控Servlet被注册了两次。虽然大多数情况下不会启动失败但日志里会出现重复绑定警告某些版本下会导致监控页面提示“初始化错误”。建议要么全部走自动配置要么全部手动注册不要混用。ConfigurationProperties(prefix spring.datasource.druid)绑定方式在Spring Boot 3中对类型校验更严格配置里如果写了不存在的参数名启动时会直接报绑定失败所以不要随意发明新的配置项。StatViewServlet在Boot 3环境下构造函数不需要参数但如果你用的是老版本Druid源码改过来的可能会发现构造器里引用了javax.servlet.http.HttpServlet编译都过不了这就是版本没换到位。5. 常见问题与排查技巧实录5.1 问题速查表我把升级过程中反复遇到的分支问题整理成了表格方便对照排查现象直接原因解决方案ClassNotFoundException: javax.servlet.Filter依赖还是老版druid-spring-boot-starter或存在javax.servlet旧包换成druid-spring-boot-3-starter排除javax.servlet依赖启动报循环依赖BeanCurrentlyInCreationException自定义DataSource和自动配置互相引用关闭自定义Bean完全走starter自动配置临时用allow-circular-references: true兜底Failed to configure a DataSource: url attribute is not specified配置前缀混乱spring.datasource.url和spring.datasource.druid.url混用统一使用spring.datasource.druid.url删除spring.datasource.type监控页面404stat-view-servlet未开启或路径被Web组件拦截yml中stat-view-servlet.enabled: true核对url-pattern和exclusions监控页面能打开但没数据web-stat-filter未开启或stat过滤器没加yml中web-stat-filter.enabled: truefilters里包含stat慢SQL一直没有记录slowSqlMillis配了但缺druid.stat.mergeSqlconnection-properties中同时配置mergeSqltrue和slowSqlMillis2000和knife4j一起用Druid页面样式丢失knife4j默认拦截包含/**的部分静态资源路径调整knife4j的静态资源映射或把Druid监控放在独立端口5.2 独家排坑的三个小技巧第一个技巧是升级完先打印Druid的连接池指标。Druid的DruidDataSource本身有getActiveCount()、getPoolingCount()这些方法写一个临时接口返回这些指标确认连接池确实正常创建了再去处理监控页面。RestController public class DruidHealthController { Resource private DataSource dataSource; GetMapping(/druid/health) public MapString, Object health() { if (dataSource instanceof DruidDataSource druidDataSource) { return Map.of( activeCount, druidDataSource.getActiveCount(), poolingCount, druidDataSource.getPoolingCount(), maxActive, druidDataSource.getMaxActive() ); } return Map.of(type, dataSource.getClass().getSimpleName()); } }Spring Boot 3的instanceof模式匹配写起来很舒服也正好能验证注入的数据源到底是不是Druid的实例。如果显示类型是HikariDataSource说明自动配置被绕过去了回去检查有没有多写spring.datasource.type。第二个技巧是在升级过程中把Druid的日志级别临时打开。在application.yml里加一行logging: level: druid: sql: DEBUG启动时就能看到Druid内部的连接获取、归还、SQL执行过程。升级阶段日志量会很大但排查问题非常直观上线前记得关回INFO。第三个技巧是用/actuator/configprops检查配置是否真的绑定到了Druid对象上。Spring Boot的actuator里有一个配置属性端点可以查看某个Bean绑定的前缀有哪些参数。如果你的spring.datasource.druid没有出现在configprops里说明自动配置没生效。使用前先确保依赖里加了spring-boot-starter-actuator并打开端点management: endpoints: web: exposure: include: configprops,health,info这个方法特别适合排查明明写了max-active: 50但连接池实际最大连接数还是20这种玄学问题。5.3 和knife4j、MyBatis-Plus一起用可能踩的联动坑这次升级顺带把接口文档工具从老版Swagger换成了knife4j因为Spring Boot 3下knife4j的适配更顺畅。knife4j-openapi3-jakarta-spring-boot-starter依赖的是springdoc的Jakarta实现和Druid监控本身没有直接冲突但有一个静态资源的映射问题knife4j默认会处理/webjars/**和/doc.html如果它把/druid/**也纳入了某个拦截路径Druid监控页面的CSS和JS就加载不出来。遇到这种情况在knife4j配置里调整资源处理路径或者给Druid监控单独指定一个独立端口都能解掉。MyBatis-Plus接入也很容易踩坑。老的mybatis-plus-boot-starter在Spring Boot 3下启动时大概率报Invalid value type for attribute factoryBeanObjectType顺着日志排查会发现结果是MyBatis-Plus版本太老没有适配MyBatis 3.5.x对Spring Boot 3的改动。换成mybatis-plus-spring-boot3-starter之后还要确认Druid的wall过滤器不会拦截MyBatis-Plus内置的一些动态SQL语法比如script标签里的多语句批量插入。如果遇到被拦截可以适当配置wall的none-base-statement-allow为true但一定要评估安全影响不要无脑放开。结尾踩过这几轮坑之后我的结论是Spring Boot 3加Druid本身并不复杂但版本细节必须死磕。我个人在实际操作中最看重的是三件事一是一定要换druid-spring-boot-3-starter不要抱着老坐标试图修修补补二是不要自己重复声明DruidDataSource和监控Servlet让starter的自动配置做它该做的事三是监控页面别图省事登录密码和IP白名单必须配齐。最后再分享一个小技巧升级完成后写一个故意慢的查询接口比如SELECT SLEEP(3)跑到Druid监控页面去看慢SQL记录。如果这条SQL能出现在慢SQL列表里说明整个Druid监控链路是通的如果没出现回头检查stat过滤器和slowSqlMillis配置。这个验证方法我每次升级完都会跑一遍基本能覆盖80%的Druid集成问题。