publicclassDriverManager{ /** * 通过检查系统属性JDBC来加载初始的JDBC驱动程序,然后使用{@code ServiceLoader}(SPI)机制 */ static { loadInitialDrivers(); println("JDBC DriverManager initialized"); } //在加载初始化的驱动中,首先根据环境变量jdbc.drivers去加载驱动,再根据SPI获取驱动实现类,SPI的驱动实现类直接通过AccessController.doPrivileged直接加载到了JVM中,环境变量加载的通过Class.forName加载JVM中,所以我们在调用Driver.getConnection不需要在之前调用Class.forName了 privatestaticvoidloadInitialDrivers(){ String drivers; try { drivers = AccessController.doPrivileged(new PrivilegedAction<String>() { public String run(){ return System.getProperty("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. // ServiceLoader.load() replaces the sun.misc.Providers()
AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run(){
/* 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 java.util.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(driversIterator.hasNext()) { driversIterator.next(); } } catch(Throwable t) { // Do nothing } returnnull; } });