類載入器——ClassLoader應用

風中有朵雲做的雨發表於2019-04-19

應用

SPI

**ServiceLoader.load(Driver.class)是Java提供載入spi的介面 **

common-logging Apache的日誌門面介面

它提供了一個介面供其他日誌元件實現org.apache.commons.logging.LogFactory 這裡以Spring Boot的demo作為例子 用slf4j做日誌管理 當我們啟動一個application 我們會先去載入SpringApplication.class 從而載入到它的靜態塊

類載入器——ClassLoader應用

類載入器——ClassLoader應用
我們只關注重點方法getFactory() debug進去會走到這裡

類載入器——ClassLoader應用
通過spi機制 會直接去讀

類載入器——ClassLoader應用

最終利用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

類載入器——ClassLoader應用
首先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 從而呼叫

類載入器——ClassLoader應用

DriverManager載入mysql的驅動實現 具體內部程式碼有興趣可以自己看看 待補充

動態代理

待補充

加密

待補充

記 可以有兩個一樣許可權包名的class檔案 如果去複製一個String然後修改到一樣相同許可權包名下 由於雙親委派機制 最終被載入的類還是rt.jar包下的

相關文章