删掉class.forname("oracle.jdbc.driver.oracledriver")即可解决java 11+应用启动慢问题,因其在jpms下触发illegalaccesserror、冗余类扫描及签名验证失败重试,而ojdbc11.jar已通过meta-inf/services自动注册驱动。
java 11+ 应用里手动调用 class.forname("oracle.jdbc.driver.oracledriver") 是启动慢的常见元凶,不是驱动本身慢,而是它触发了模块化环境下的类加载冲突和非法访问检查,导致初始化卡顿数秒甚至更久。
删掉所有 Class.forName 调用
ojdbc11.jar 通过 META-INF/services/java.sql.Driver 自动注册驱动,Class.forName 不仅多余,还会在 JPMS 下抛 IllegalAccessError 或触发冗余类扫描。
- 搜索整个项目(含测试、工具类、配置类),彻底删除所有形如
Class.forName("oracle.jdbc.driver.OracleDriver")的语句 - 若需动态加载(如多数据源切换),改用新类名:
Class.forName("oracle.jdbc.OracleDriver")—— 旧类名在 ojdbc11 中只是空壳 - 验证是否生效:启动后打印
DriverManager.getDrivers(),输出中应含oracle.jdbc.OracleDriver@xxx,而非旧包路径
确认 ojdbc11.jar 来源合法且带签名
从 Maven Central 拉取 com.oracle.database.jdbc:ojdbc11:23.5.0.23.09,别用网上“免安装版”或本地解压的 jar。缺签名会触发 SecurityException,JVM 在验证阶段反复重试,拖慢启动。
- 检查 jar 包内是否存在
META-INF/*.SF和META-INF/*.DSA文件 - 运行
jar -tvf ojdbc11-23.5.0.23.09.jar | grep -i signature确认签名存在 - 若用自建 Nexus,确保代理仓库未 strip 签名(尤其启用 checksum 验证时)
避免 DNS 解析阻塞驱动注册流程
驱动注册本身不涉及网络,但某些旧版封装逻辑或应用层预热代码会在 DriverManager.registerDriver 后立刻尝试解析 URL 中的主机名——此时若 DNS 响应慢,InetAddress.getByName() 会阻塞主线程。
- 不要在
static块或 Spring@PostConstruct中执行InetAddress.getByName("db-host") - 若必须用域名,启动前加 JVM 参数:
-Dsun.net.inetaddr.ttl=30 -Dsun.net.inetaddr.negative.ttl=30,避免缓存失败结果太久 - 最稳妥方式:JDBC URL 改用 IP 直连,例如
jdbc:oracle:thin:@//192.168.10.5:1521/ORCLPDB1(注意双斜杠)
真正耗时的往往不是驱动加载本身,而是残留的 Class.forName 触发的模块系统检查、签名验证失败后的退避重试、或 URL 主机名引发的隐式 DNS 查询——这三者叠加,会让“驱动加载慢”看起来像一个黑盒问题。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











