Tomcat9 ConnectionPool.init忽略自定义DataSource加密密码失效问题
问题解决思路
第一类:排查自定义类是否正常加载实例化
- 首先解压部署的war包,确认
WEB-INF/classes/com/mypackage/CustomDataSource.class存在,且对应为你修改后的带打印逻辑的版本,同时确认Spring配置文件中bean的class属性拼写完全正确,没有拼写错误。 - 在
CustomDataSource的无参构造方法中新增初始化日志打印,重新打包部署后查看日志是否有对应输出:
public CustomDataSource() { System.out.println("自定义DataSource已实例化"); }
如果构造方法日志未输出,说明Spring根本没有实例化你自定义的类,继续往下排查:
- 检查是否存在同ID(
MySQLSource)的其他Bean定义覆盖了你的配置:比如注解配置、其他导入的xml配置中存在同名Bean,不同Spring版本对Bean覆盖的默认处理规则不同,可在Spring配置中开启Bean定义覆盖日志确认。 - 检查故障环境加载的Spring配置文件是否为最新版本:部分场景下服务器可能存在缓存的旧配置文件未被覆盖,可删除Tomcat的work、temp目录后重新部署。
第二类:排查类加载/继承重写异常
- 你当前的
setPassword方法没有添加@Override注解,先补充该注解重新编译,确认父类存在同签名的方法,避免因为Tomcat版本差异导致父类方法签名变更,重写失效。 - 排查Tomcat类加载优先级冲突:如果故障服务器的
Tomcat/lib目录下存在tomcat-jdbc.jar,而你的web应用WEB-INF/lib下也存在同依赖的不同版本,会导致类加载混乱。你可以统一依赖版本,或者将自定义的CustomDataSource类也放到Tomcat的lib目录下,保证和父类DataSource使用同一个类加载器加载。 - 排查JDK11模块系统影响:OpenJDK11引入了模块化机制,如果你项目中配置了
module-info.java,需要确认对org.apache.tomcat.jdbc模块的访问权限已经开放。
第三类:排查连接池初始化时序问题
- 你看到的警告
Not loading a JDBC driver as driverClassName property is null可以先修复:在Bean配置中添加driverClassName属性,指定MySQL驱动类:
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
- 部分场景下连接池会在所有属性注入完成前提前初始化,你可以在Bean配置中添加
lazy-init="true"属性,延迟连接池初始化,保证密码解密逻辑在连接创建前执行:
<bean id="MySQLSource" class="com.mypackage.CustomDataSource" destroy-method="close" lazy-init="true">
如果上述方案仍无法解决,你可以改用更稳定的Bean后置处理器方案实现密码解密,无需继承DataSource,兼容性更强:
@Component public class DataSourcePasswordProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof org.apache.tomcat.jdbc.pool.DataSource) { org.apache.tomcat.jdbc.pool.DataSource dataSource = (org.apache.tomcat.jdbc.pool.DataSource) bean; String encodedPwd = dataSource.getPoolProperties().getPassword(); Crypt crypt = new Crypt(); String decodePassword = crypt.decryptValue(encodedPwd); dataSource.getPoolProperties().setPassword(decodePassword); } return bean; } }
该方案会拦截所有Tomcat DataSource实例的初始化过程,统一处理密码解密,不受类加载、Bean继承规则的影响,兼容所有JDK和Tomcat版本。
内容的提问来源于stack exchange,提问作者italo
相关产品推荐
相关产品推荐

