一,jdbc连接驱动器的注册加载
Class.forName("com.mysql.jdbc.Driver");
当以上类被装载时执行以下程序
package com.mysql.jdbc; import java.sql.SQLException; public class Driver extends NonRegisteringDriver implements java.sql.Driver { //执行这个静态代码块 static { try {//注册mysql实现的驱动类 java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } } public Driver() throws SQLException { // Required for Class.forName().newInstance() } }
进入java.sql.DriverManager.registerDirver(new Driver());中的功能实现
public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException { if (!initialized) { //初始化动作在下面作详解 initialize(); } //用来存储驱动器信息 DriverInfo di = new DriverInfo(); di.driver = driver; di.driverClass = driver.getClass(); di.driverClassName = di.driverClass.getName(); // Not Required -- drivers.addElement(di); //用于加入驱动的集合 writeDrivers.addElement(di); println("registerDriver: " + di); /* 用于读取驱动的集合 */ readDrivers = (java.util.Vector) writeDrivers.clone(); //用以上两个集合达到读写分离的状态,由 Vector 的 iterator 和 listIterator 方法所返回的迭代器是快速失败的 }
二,驱动器的初始化操作
static void initialize() { if (initialized) { return; } //private static boolean initialized = false;静态全局变量,只初始化一次 initialized = true; loadInitialDrivers(); println("JDBC DriverManager initialized"); }
实现初始化操作
private static void loadInitialDrivers() { String drivers; try {//得到系统属性jdbc.drivers对应驱动的驱动名称,使用了JAVA的安全许可 drivers = (String) java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction("jdbc.drivers")); } catch (Exception ex) { drivers = null; } // If the driver is packaged as a Service Provider, // load it. // Get all the drivers through the classloader // exposed as a java.sql.Driver.class service. DriverService ds = new DriverService(); // Have all the privileges to get all the // implementation of java.sql.Driver java.security.AccessController.doPrivileged(ds); println("DriverManager.initialize: jdbc.drivers = " + drivers); if (drivers == null) { return; } while (drivers.length() != 0) { int x = drivers.indexOf(':'); String driver; if (x < 0) { driver = drivers; drivers = ""; } else { driver = drivers.substring(0, x); drivers = drivers.substring(x+1); } if (driver.length() == 0) { continue; } try { println("DriverManager.Initialize: loading " + driver); Class.forName(driver, true, ClassLoader.getSystemClassLoader()); } catch (Exception ex) { println("DriverManager.Initialize: load failed: " + ex); } } }
以上初始化代码分析
内部类对象,创建此对象时,它会从系统服务中加载驱动
DriverService ds = new DriverService();
代码如下:
class DriverService implements java.security.PrivilegedAction {
Iterator ps = null; public DriverService() {}; public Object run() { //从系统服务中加载驱动 ps = Service.providers(java.sql.Driver.class); /* Load these drivers, so that they can be instantiated. * It may be the case that the driver class may not be there * i.e. there may be a packaged driver with the service class * as implementation of java.sql.Driver but the actual class * may be missing. In that case a sun.misc.ServiceConfigurationError * will be thrown at runtime by the VM trying to locate * and load the service. * * Adding a try catch block to catch those runtime errors * if driver not available in classpath but it's * packaged as service and that service is there in classpath. */ try { while (ps.hasNext()) { ps.next();//遍历所有的驱动 } // end while } catch(Throwable t) { // Do nothing } return null; } //end run }
//使用特权去获取ds java.security.AccessController.doPrivileged(ds);