DriverManager类

  1 /**管理一个集合JDBC驱动的基础服务
  2 注意:在新的JDBC2.0api中实现了新的DataSource接口,提供了另一种链接数据源的方式。
  3 使用DataSource的对象是首选方案
  4 */
  5 public class DriverManager {
  6 
  7     // 注册了JDBC驱动的集合
  8     private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();
  9   
 10     /**
 11     通过检查jdcb.properties加载初始化JDBC驱动
 12      */
 13     static {
 14         loadInitialDrivers();
 15         println("JDBC DriverManager initialized");
 16     }
 17 
 18 /*
 19 *对外使用提供数据库连接的方法,
 20 *重点说明Reflection.getCallerClass()方法,该方法返回调用者的类
 21 */
 22     @CallerSensitive
 23     public static Connection getConnection(String url)
 24         throws SQLException {
 25 
 26         java.util.Properties info = new java.util.Properties();
 27         return (getConnection(url, info, Reflection.getCallerClass()));
 28     }
 29 
 30     //  用于根据url、对应的属性信息在registeredDrivers中找到合适的注册的驱动创建数据库链接
 31     private static Connection getConnection(
 32         String url, java.util.Properties info, Class<?> caller) throws SQLException {
 33         /*
 34          * When callerCl is null, we should check the application's
 35          * (which is invoking this class indirectly)
 36          * classloader, so that the JDBC driver class outside rt.jar
 37          * can be loaded from here.
 38          */
 39         ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
 40         synchronized(DriverManager.class) {
 41             // synchronize loading of the correct classloader.
 42             if (callerCL == null) {
 43                 callerCL = Thread.currentThread().getContextClassLoader();
 44             }
 45         }
 46 
 47         if(url == null) {
 48             throw new SQLException("The url cannot be null", "08001");
 49         }
 50 
 51         println("DriverManager.getConnection("" + url + "")");
 52 
 53         // Walk through the loaded registeredDrivers attempting to make a connection.
 54         // Remember the first exception that gets raised so we can reraise it.
 55         SQLException reason = null;
 56 
 57         for(DriverInfo aDriver : registeredDrivers) {
 58             // If the caller does not have permission to load the driver then
 59             // skip it.
 60          //一个应用中有可能会有多个数据库驱动,需要判断数据库连接的调用者(调用getConnection()方法的对象)是否与驱动相匹配
 61             if(isDriverAllowed(aDriver.driver, callerCL)) {
 62                 try {
 63                     println("    trying " + aDriver.driver.getClass().getName());
 64                     Connection con = aDriver.driver.connect(url, info);
 65                     if (con != null) {
 66                         // Success!
 67                         println("getConnection returning " + aDriver.driver.getClass().getName());
 68                         return (con);
 69                     }
 70                 } catch (SQLException ex) {
 71                     if (reason == null) {
 72                         reason = ex;
 73                     }
 74                 }
 75 
 76             } else {
 77                 println("    skipping: " + aDriver.getClass().getName());
 78             }
 79 
 80         }
 81 
 82         // if we got here nobody could connect.
 83         if (reason != null)    {
 84             println("getConnection failed: " + reason);
 85             throw reason;
 86         }
 87 
 88         println("getConnection: no suitable driver found for "+ url);
 89         throw new SQLException("No suitable driver found for "+ url, "08001");
 90     }
 91 }
 92 
 93 //一个应用中有可能会有多个数据库驱动,需要判断数据库连接的调用者(调用getConnection()方法的对象)是否与驱动相匹配
 94 private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) {
 95         boolean result = false;
 96         if(driver != null) {
 97             Class<?> aClass = null;
 98             try {
 99                 aClass =  Class.forName(driver.getClass().getName(), true, classLoader);
100             } catch (Exception ex) {
101                 result = false;
102             }
103 
104              result = ( aClass == driver.getClass() ) ? true : false;
105         }
106 
107         return result;
108     }
109 
110 //根据URL从registeredDrivers 中获得驱动,根据Reflection.getCallerClass()返回的调用者类,在registeredDrivers 中进行匹配
111   @CallerSensitive
112     public static Driver getDriver(String url)
113         throws SQLException {
114 
115         println("DriverManager.getDriver("" + url + "")");
116 
117         Class<?> callerClass = Reflection.getCallerClass();
118 
119         // Walk through the loaded registeredDrivers attempting to locate someone
120         // who understands the given URL.
121         for (DriverInfo aDriver : registeredDrivers) {
122             // If the caller does not have permission to load the driver then
123             // skip it.
124             if(isDriverAllowed(aDriver.driver, callerClass)) {
125                 try {
126                     if(aDriver.driver.acceptsURL(url)) {
127                         // Success!
128                         println("getDriver returning " + aDriver.driver.getClass().getName());
129                     return (aDriver.driver);
130                     }
131 
132                 } catch(SQLException sqe) {
133                     // Drop through and try the next driver.
134                 }
135             } else {
136                 println("    skipping: " + aDriver.driver.getClass().getName());
137             }
138 
139         }
140 
141         println("getDriver: no suitable driver");
142         throw new SQLException("No suitable driver", "08001");
143     }
144 
145 
146 /*
147 *注册数据驱动,使用同步方式,最终保存在CopyOnWriteArrayList的集合中
148 */
149     public static synchronized void registerDriver(java.sql.Driver driver,
150             DriverAction da)
151         throws SQLException {
152 
153         /* Register the driver if it has not already been added to our list */
154         if(driver != null) {
155             registeredDrivers.addIfAbsent(new DriverInfo(driver, da));
156         } else {
157             // This is for compatibility with the original DriverManager
158             throw new NullPointerException();
159         }
160 
161         println("registerDriver: " + driver);
162 
163     }
收藏文章数量从多到少与“把书读薄”是一个道理
原文地址:https://www.cnblogs.com/use-D/p/9570340.html