|
6 | 6 | import java.sql.*; |
7 | 7 | import java.util.Enumeration; |
8 | 8 | import java.util.Properties; |
| 9 | +import java.util.concurrent.ConcurrentHashMap; |
| 10 | +import java.util.concurrent.ConcurrentMap; |
| 11 | +import java.util.logging.Level; |
9 | 12 | import java.util.logging.Logger; |
10 | 13 |
|
11 | 14 | public class AuthorizationJdbcDriver implements Driver { |
12 | 15 |
|
13 | | - private Driver driver; |
| 16 | + private static final ConcurrentMap<String, Driver> DRIVER_CACHE = new ConcurrentHashMap<>(); |
| 17 | + private static final Logger LOGGER = Logger.getLogger(AuthorizationJdbcDriver.class.getName()); |
| 18 | + |
| 19 | + static { |
| 20 | + try { |
| 21 | + DriverManager.registerDriver(new AuthorizationJdbcDriver()); |
| 22 | + } catch (Exception e) { |
| 23 | + LOGGER.log(Level.SEVERE, "Failed to register AuthorizationJdbcDriver", e); |
| 24 | + throw new RuntimeException("Failed to register AuthorizationJdbcDriver", e); |
| 25 | + } |
| 26 | + LOGGER.info("AuthorizationJdbcDriver initialized and registered"); |
| 27 | + } |
| 28 | + |
14 | 29 |
|
15 | 30 | @Override |
16 | 31 | public Connection connect(String url, Properties info) throws SQLException { |
| 32 | + if (url == null) { |
| 33 | + throw new SQLException("URL cannot be null"); |
| 34 | + } |
| 35 | + |
| 36 | + Driver driver = findDriver(url); |
| 37 | + if (driver == null) { |
| 38 | + throw new SQLException("No suitable driver found for " + url); |
| 39 | + } |
17 | 40 | return new ConnectionProxy(driver.connect(url, info)); |
18 | 41 | } |
19 | 42 |
|
20 | | - @Override |
21 | | - public boolean acceptsURL(String url) throws SQLException { |
| 43 | + |
| 44 | + /** |
| 45 | + * 查找接受指定 URL 的真实 JDBC 驱动 |
| 46 | + * |
| 47 | + * @param url JDBC URL |
| 48 | + * @return 真实的 JDBC 驱动,如果未找到则返回 null |
| 49 | + */ |
| 50 | + private Driver findDriver(String url) throws SQLException { |
| 51 | + if (url == null) { |
| 52 | + return null; |
| 53 | + } |
| 54 | + |
| 55 | + // 从缓存中查找(使用 URL 前缀作为 key) |
| 56 | + Driver cachedDriver = DRIVER_CACHE.get(url); |
| 57 | + if (cachedDriver != null) { |
| 58 | + try { |
| 59 | + // 验证缓存的驱动仍然接受该 URL |
| 60 | + if (cachedDriver.acceptsURL(url)) { |
| 61 | + return cachedDriver; |
| 62 | + } else { |
| 63 | + // 如果缓存的驱动不再接受该 URL,从缓存中移除 |
| 64 | + DRIVER_CACHE.remove(url, cachedDriver); |
| 65 | + } |
| 66 | + } catch (SQLException e) { |
| 67 | + // 如果验证失败,从缓存中移除并继续查找 |
| 68 | + DRIVER_CACHE.remove(url, cachedDriver); |
| 69 | + LOGGER.log(Level.FINE, "Cached driver no longer accepts URL: " + url, e); |
| 70 | + } |
| 71 | + } |
| 72 | + |
| 73 | + // 遍历所有已注册的驱动 |
22 | 74 | Enumeration<Driver> drivers = DriverManager.getDrivers(); |
23 | 75 | while (drivers.hasMoreElements()) { |
24 | 76 | Driver driver = drivers.nextElement(); |
25 | | - if (driver.acceptsURL(url)) { |
26 | | - this.driver = driver; |
27 | | - return true; |
| 77 | + if (driver.getClass().equals(AuthorizationJdbcDriver.class)) { |
| 78 | + continue; |
| 79 | + } |
| 80 | + try { |
| 81 | + if (driver.acceptsURL(url)) { |
| 82 | + // 缓存驱动(使用 URL 的前缀作为 key,因为同一个数据库类型的 URL 前缀相同) |
| 83 | + DRIVER_CACHE.putIfAbsent(url, driver); |
| 84 | + return driver; |
| 85 | + } |
| 86 | + } catch (SQLException e) { |
| 87 | + // 忽略单个驱动的异常,继续查找 |
| 88 | + LOGGER.log(Level.FINE, "Driver " + driver.getClass().getName() + " does not accept URL: " + url, e); |
28 | 89 | } |
29 | 90 | } |
30 | | - return false; |
| 91 | + return null; |
| 92 | + } |
| 93 | + |
| 94 | + @Override |
| 95 | + public boolean acceptsURL(String url) throws SQLException { |
| 96 | + if (url == null) { |
| 97 | + return false; |
| 98 | + } |
| 99 | + Driver driver = findDriver(url); |
| 100 | + return driver != null; |
31 | 101 | } |
32 | 102 |
|
33 | 103 | @Override |
34 | 104 | public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { |
| 105 | + Driver driver = findDriver(url); |
| 106 | + if (driver == null) { |
| 107 | + throw new SQLException("No suitable driver found for " + url); |
| 108 | + } |
35 | 109 | return driver.getPropertyInfo(url, info); |
36 | 110 | } |
37 | 111 |
|
38 | 112 | @Override |
39 | 113 | public int getMajorVersion() { |
40 | | - return driver.getMajorVersion(); |
| 114 | + // 返回代理驱动的主版本号 |
| 115 | + return 1; |
41 | 116 | } |
42 | 117 |
|
43 | 118 | @Override |
44 | 119 | public int getMinorVersion() { |
45 | | - return driver.getMinorVersion(); |
| 120 | + // 返回代理驱动的次版本号 |
| 121 | + return 0; |
46 | 122 | } |
47 | 123 |
|
48 | 124 | @Override |
49 | 125 | public boolean jdbcCompliant() { |
50 | | - return driver.jdbcCompliant(); |
| 126 | + // 代理驱动本身不直接兼容 JDBC,它依赖于底层驱动 |
| 127 | + return false; |
51 | 128 | } |
52 | 129 |
|
| 130 | + |
53 | 131 | @Override |
54 | 132 | public Logger getParentLogger() throws SQLFeatureNotSupportedException { |
55 | | - return driver.getParentLogger(); |
| 133 | + return LOGGER; |
56 | 134 | } |
57 | 135 | } |
0 commit comments