gpt4 book ai didi

java - 为什么 DriverManager.getConnection 不使用 Driver.class 中的 "acceptsURL"方法

转载 作者:行者123 更新时间:2023-11-29 04:06:02 26 4
gpt4 key购买 nike

我正在阅读 JDBC 代码。在 DriverManager.getConnection 中,我发现它是这样工作的:它尝试连接它知道的每个驱动程序,直到成功为止。

代码如下:

        for(DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
if(isDriverAllowed(aDriver.driver, callerCL)) {
try {
println(" trying " + aDriver.driver.getClass().getName());
Connection con = aDriver.driver.connect(url, info);
if (con != null) {
// Success!
println("getConnection returning " + aDriver.driver.getClass().getName());
return (con);
}
} catch (SQLException ex) {
if (reason == null) {
reason = ex;
}
}

} else {
println(" skipping: " + aDriver.getClass().getName());
}

}

但是接口(interface)驱动程序中有一个方法“acceptsURL”:

    boolean acceptsURL(String url) throws SQLException;

所以我的问题是,为什么 DriverManager 在进行真正的连接之前不调用这个方法来过滤不相关的驱动程序?

或者使用代码,这可能更好吗?

        for(DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
if(isDriverAllowed(aDriver.driver, callerCL) && aDriver.driver.acceptsURL(url)) {
try {
println(" trying " + aDriver.driver.getClass().getName());
Connection con = aDriver.driver.connect(url, info);
if (con != null) {
// Success!
println("getConnection returning " + aDriver.driver.getClass().getName());
return (con);
}
} catch (SQLException ex) {
if (reason == null) {
reason = ex;
}
}

} else {
println(" skipping: " + aDriver.getClass().getName());
}

}

最佳答案

DriverManager 引用实现 (OpenJDK) 不使用 acceptsUrl。这并不一定意味着没有 DriverManager 实现在使用它。事实上,据我所知,早期的 Sun Java 实现确实调用了 acceptsURL。它未被调用的主要原因是 JDBC 规范要求 DriverManager 无论如何都要在每个已注册的驱动程序上调用 connect。见下文。

规范或 API 文档中没有任何内容表明 DriverManager 必须使用 acceptsURL。此处的 JDBC 4.3 specification 仅表示(第 9.2 节 Driver 接口(interface)):

The DriverManager class invokes Driver methods when it wishes to interact with a registered driver. The Driver interface also includes the method acceptsURL. The DriverManager can use this method to determine which of its registered drivers it should use for a given URL.

(强调我的)

请注意使用可以而不是必须

随后的段落说:

When the DriverManager is trying to establish a connection, it calls that driver’s connect method and passes the driver the URL. If the Driver implementation understands the URL, it will return a Connection object or throw a SQLException if a connection cannot be maded [sic] to the database. If the Driver implementation does not understand the URL, it will return null.

此外,第 9.4 节 DriverManager 说:

  • getConnection — the method the JDBC client invokes to establish a connection. The invocation includes a JDBC URL, which the DriverManager passes to each driver in its list until it finds one whose Driver.connect method recognizes the URL. That driver returns a Connection object to the DriverManager, which in turn passes it to the application.

(强调我的)

我是怎么读的,无论如何都需要在每个驱动程序上调用 Driver.connect,因此实现调用 acceptsURL 没有意义。

现在,至于 JDBC 规范为什么这样写,我不知道,我自己也是 JSR-221 (JDBC 4) 专家组的成员。当我加入专家组时,实现(和规范)已经是这样了,所以我不知道它的历史。但是,我不确定您在这里会得到比上述令人不满意的答案更好的答案(之所以如此,是因为规范如此规定)。

但是,如果我不得不猜测的话,这可能是因为对于某些驱动程序来说,确定他们是否可以接受 URL 可能相对复杂或昂贵。在这种情况下,最好尝试连接,因为对于拒绝 URL 的驱动程序,成本与调用 acceptsURL 相同(或应该),而对于实际接受 URL 的驱动程序URL,如果 DriverManager 首先调用 acceptsURL,然后调用 connect,成本将增加两次。

这并不意味着 acceptsURL 方法完全没有值(value)。一些应用程序(例如一些查询工具或报告工具)使用它来发现哪些驱动程序将处理特定的 URL,因此它们可以询问 Driver 实现以获取其支持的连接属性( Driver.getPropertyInfo​ ) 以便他们可以使用可用属性填充连接向导。其他程序可以使用它来获取信息,例如版本(Driver.getMajorVersionDriver.getMinorVersion)、父记录器(Driver.getParentLogger)或 JDBC 兼容性(Driver.jdbcCompliant)。

关于java - 为什么 DriverManager.getConnection 不使用 Driver.class 中的 "acceptsURL"方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58648405/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com