天天看点

java破坏双亲委派_JDBC 是如何破坏双亲委派机制的?

上面使用Class.forName的方式注册驱动是比较古老的方式拉,新的DriverManager中会通过SPI机制自动加载驱动,只要classpath中有相应的驱动包即可。

在新的版本中,不需要显式的加载驱动,直接DriverManager.getConnection即可。

新的DriverManager加载驱动的过程是在loadInitialDrivers方法中进行的。

//加载驱动类有两种方式,

//1种是通过jdbc.drivers设置驱动类的位置,然后通过SystemClassLoader

//另外一种通过spi机制加载

private static void loadInitialDrivers() {

String drivers;

try {

drivers = AccessController.doPrivileged(new PrivilegedAction() {

public String run() {

return System.getProperty("jdbc.drivers");

}

});

} catch (Exception ex) {

drivers = null;

}

AccessController.doPrivileged(new PrivilegedAction() {

public Void run() {

//在这里会通过Thread.currentThread().getContextClassLoader()加载

ServiceLoader loadedDrivers = ServiceLoader.load(Driver.class);

Iterator driversIterator = loadedDrivers.iterator();

try{

while(driversIterator.hasNext()) {

driversIterator.next();

}

} catch(Throwable t) {

// Do nothing

}

return null;

}

});

println("DriverManager.initialize: jdbc.drivers = " + drivers);

if (drivers == null || drivers.equals("")) {

return;

}

String[] driversList = drivers.split(":");

println("number of Drivers:" + driversList.length);

for (String aDriver : driversList) {

try {

println("DriverManager.Initialize: loading " + aDriver);

//这里是通过SystemLoader加载

Class.forName(aDriver, true,

ClassLoader.getSystemClassLoader());

} catch (Exception ex) {

println("DriverManager.Initialize: load failed: " + ex);

}

}

}

上面的方法知识加载驱动类,具体的注册逻辑在Driver类中,可查看Driver接口的说明: