**ServiceLoader.load(Driver.class)是Java提供加載spi的接口 **java
它提供了一個接口供其餘日誌組件實現org.apache.commons.logging.LogFactory 這裏以Spring Boot的demo做爲例子 用slf4j作日誌管理 當咱們啓動一個application 咱們會先去加載SpringApplication.class 從而加載到它的靜態塊mysql
最終利用spi拿到這個SLF4JLogFactory去實現這個org.apache.commons.logging.LogFactory日誌接口sql
jdbc4.0之前,開發人員還須要基於Class.forName("xxx")的方式來裝載驅動,jdbc4也基於spi的機制來發現驅動提供商了,能夠經過META-INF/services/java.sql.Driver文件裏指定實現類的方式來暴露驅動提供數據庫
//4.0之前 拿數據庫鏈接
Class.forName("com.mysql.jdbc.Driver");//初始化class(不是實例化) 加載static塊
Connection con = DriverManager.getConnection(url,user,psw);
複製代碼
//4.0之後 拿數據庫鏈接
Connection con = DriverManager.getConnection(url,user,psw);
複製代碼
開始分析 這裏咱們使用mysql的驅動 mysql-connector-java.jarapache
static {
loadInitialDrivers();
println("JDBC DriverManager initialized");
}
複製代碼
進入loadInitialDrivers 重要代碼以下bash
ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
Iterator<Driver> driversIterator = loadedDrivers.iterator();
while(driversIterator.hasNext()) {
driversIterator.next();
}
複製代碼
使用spi獲取driver的實現 這裏也會初始化Driver.class 從而調用app
DriverManager加載mysql的驅動實現 具體內部代碼有興趣能夠本身看看 待補充加密
待補充url
待補充spa
記 能夠有兩個同樣權限包名的class文件 若是去複製一個String而後修改到同樣相同權限包名下 因爲雙親委派機制 最終被加載的類仍是rt.jar包下的