應用
SPI
**ServiceLoader.load(Driver.class)是Java提供載入spi的介面 **
common-logging Apache的日誌門面介面
它提供了一個介面供其他日誌元件實現org.apache.commons.logging.LogFactory 這裡以Spring Boot的demo作為例子 用slf4j做日誌管理 當我們啟動一個application 我們會先去載入SpringApplication.class 從而載入到它的靜態塊
我們只關注重點方法getFactory() debug進去會走到這裡 通過spi機制 會直接去讀最終利用spi拿到這個SLF4JLogFactory去實現這個org.apache.commons.logging.LogFactory日誌介面
JDBC
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.jar
首先DriverManager有這麼段靜態程式碼static {
loadInitialDrivers();
println("JDBC DriverManager initialized");
}
複製程式碼
進入loadInitialDrivers 重要程式碼如下
ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
Iterator<Driver> driversIterator = loadedDrivers.iterator();
while(driversIterator.hasNext()) {
driversIterator.next();
}
複製程式碼
使用spi獲取driver的實現 這裡也會初始化Driver.class 從而呼叫
DriverManager載入mysql的驅動實現 具體內部程式碼有興趣可以自己看看 待補充
動態代理
待補充
加密
待補充
記 可以有兩個一樣許可權包名的class檔案 如果去複製一個String然後修改到一樣相同許可權包名下 由於雙親委派機制 最終被載入的類還是rt.jar包下的