java - 从外部 JAR 加载不带名称的 JDBC 驱动程序
问题描述
我希望用户决定使用什么数据库。他应该只提供连接器 JAR 文件和数据库 URL。
问题是,我不知道驱动程序的类名。
是否可以使用 a 加载 JARURLClassLoader
并在不知道名称的情况下注册驱动程序。到目前为止,我只找到了已知驱动程序名称的解决方案。
我还尝试添加一个相对于我导出的 JAR 文件的类路径的目录(使用 maven 程序集插件),但它不起作用。
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Class-Path>libs/*</Class-Path>
</manifestEntries>
</archive>
</configuration>
任何帮助,将不胜感激。
解决方案
所有符合 JDBC 4 和更高版本的驱动程序都包含一个服务定义文件,用于java.util.ServiceLoader
. 如果您的应用程序在初始类路径上有驱动程序,则无需执行任何操作,因为java.sql.DriverManager
会自动加载这些驱动程序。
如果驱动程序位于辅助类路径上(例如,在 Web 应用程序上下文中,或手动初始化的类加载器中),那么您将需要手动加载驱动程序以使其注册。在这种情况下,应该可以使用ServiceLoader
自己来枚举该上下文的类路径上的所有可用驱动程序。
这可以用ServiceLoader.load(Class<S> service)
或来完成ServiceLoader.load(Class<S> service, ClassLoader loader)
。然后,您可以迭代(或流式传输)可用驱动程序的实例(这将自动注册它们DriverManager
)。
例如
ServiceLoader<Driver> drivers = ServiceLoader.load(java.sql.Driver.class, yourClassLoader);
for (Driver driver : drivers) {
System.out.println(driver.getClass().getName());
}
您唯一需要知道的是要连接的正确 JDBC url。
请注意,如果您的类加载器的生命周期很短,这可能会导致内存泄漏:您需要显式取消注册驱动程序以避免此类泄漏。
推荐阅读
- sql - 来自选择查询的一个单元格中的多个值
- elasticsearch - Elasticsearch 2.4 搜索过滤器:将术语与正则表达式混合
- javascript - 使用 react-router-dom 构建 reactjs 后显示空白页面
- keras - 带 GRU 模块的以 10 为底的 int() 的无效文字
- php - PHP 内存耗尽,继承代码导致较大文件出错,我是刷新内存、批处理还是增加内存分配?
- swift - 有没有更好的方法来优化这个 Firestore 查询?
- scala - 如何解决 Kafka Consumer 轮询超时错误
- javascript - 在大屏幕上禁用 Fullpage.js
- javascript - 反应:在用户导航之前恢复滚动位置/调用 history.replace()
- html - 保持与缩放的同级对齐而不进行反向缩放