最近项目中需要对已提供数据库钥匙的数据源进行查询,考虑到各方数据库版本不一致,单一jdbc驱动恐无法满足需要,故产生单个项目连接多JDBC驱动版本的想法
由于本篇文章涉及到ClassLoader的相关知识,建议未了解过的朋友通过如下博客自行了解 彻底理解ClassLoader
实现此功能的过程中参考了如下博文: 动态加载jdbc驱动(可测试jdbc不同版本兼容性) Java 自定义 ClassLoader 实现隔离运行不同版本jar包的方式
通过替换当前项目的jar包,获取DB连接得出各版本驱动连接8.0.21的结果
public class SingleDriverTest { public static void main(String[] args) throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); DriverManager.getConnection("jdbc:mysql://localhost:3306/demo","root","123456"); /* v3.1.14: Exception in thread "main" java.sql.SQLException: Client does not support authentication protocol requested by server; consider upgrading MySQL client at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2975) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:798) at com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:3700) at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1203) at com.mysql.jdbc.Connection.createNewIO(Connection.java:2572) at com.mysql.jdbc.Connection.<init>(Connection.java:1485) at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:266) at java.sql.DriverManager.getConnection(DriverManager.java:664) at java.sql.DriverManager.getConnection(DriverManager.java:247) at pub.ikkyu.test.SingleDriverTest.main(SingleDriverTest.java:14) */ /* v5.0.8: Exception in thread "main" com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Client does not support authentication protocol requested by server; consider upgrading MySQL client at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:921) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:885) at com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:3421) at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1247) at com.mysql.jdbc.Connection.createNewIO(Connection.java:2775) at com.mysql.jdbc.Connection.<init>(Connection.java:1555) at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285) at java.sql.DriverManager.getConnection(DriverManager.java:664) at java.sql.DriverManager.getConnection(DriverManager.java:247) at pub.ikkyu.test.SingleDriverTest.main(SingleDriverTest.java:14) */ /* v5.1.47: Tue Sep 01 11:40:54 CST 2020 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification. */ /* v8.0.16 Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary. */ } }整个工具类代码最核心的部分如下:
// 保留原始ClassLoader ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(loader); // 还原原始ClassLoader Thread.currentThread().setContextClassLoader(oldClassLoader);如果不设置当前线程的ClassLoader,则可能会出现ClassLoader默认为AppClassLoader,导致相同全限定名的类只会加载一次,从而达不到预期的目标的问题