上面使用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接口的说明: