天天看點

類加載器與雙親委派機制

1.什麼是類加載器

就是将我們的位元組碼(class檔案)讀取到JVM記憶體中。

2.讀取class檔案來源

1:本地磁盤檔案 java代碼變為的class檔案

2:通過網絡下載下傳的class檔案

3:War、jar 解壓的class檔案

4:從專門的資料庫中讀取的class檔案

5:使用 java cglib、動态代理生成的代理類class檔案

3.類加載的分類

1.啟動(Bootstrap)類加載器:加載JVM自身工作需要的類,它由JVM自己實作。它會加載$JAVA_HOME/jre/lib下的檔案 底層是C語言實作

2.擴充(Extension)類加載器:它是JVM的一部分,由sun.misc.LauncherExtClassLoader實作,他會加載ExtClassLoader實作,他會加載ExtClassLoader實作,他會加載JAVA_HOME/jre/lib/ext目錄中的檔案(或由System.getProperty(“java.ext.dirs”)所指定的檔案)。 底層是Java實作

3.(應用)AppClassLoader 類加載器:應用類加載器,我們工作中接觸最多的也是這個類加載器,它由sun.misc.Launcher$AppClassLoader實作。他加載我們工程目錄classpath下的class及jar包  底層是java實作

4.自定義類加載器: 也就是使用者自己定義的類加載器

類加載器執行順序圖:

類加載器與雙親委派機制

 類加載器分類職能圖:

類加載器與雙親委派機制

4.那些操作會觸發類加載操作

類的主動使用:

1. 調用類的靜态方法

2. invokeStatic   調用靜态方法

3. Main

4. New

5. Class.formname

6. 子類初始化一定會初始化父類 初始化一個類,那麼一定會觸發類加載器 但是類加載器加載了該類,但是該類不一定初始化。

5.類加載器的雙親委派機制

首先在我們類加載器分為四種 自定義類加載器、應用類加載器、擴充類加載器、啟動類加載器。

當一個類加載器收到請求之後,首先會依次向上查找到最頂層類加載器(啟動類加載器),依次向下加載class檔案,如果已經加載到class檔案,子加載器不會加繼續加載該class檔案。

6.雙親委派機制的好處

依次向上查找最頂端啟動類加載器讀取class檔案,隻要啟動類加載器讀取成功之後,以後不會再擴充、應用類加載器讀取。

目的:就是為了防禦開發者定義的類與jdk定義源碼類産生沖突問題,保證該類在記憶體中的唯一性。

7.ClassLoader源碼解讀

類加載器與雙親委派機制

 8.預設目前線程關聯的是應用類加載器(Launcher類)

類加載器與雙親委派機制

 9.如何破壞雙親委派原則

雙親委派代碼在loadclass方法中,隻需要繞開loadclass方法即可。

1:自定義類加載器  重寫loadclass方法。

2:Spi機制繞開loadclass方法,目前線程設定關聯類加載器。

Spi機制繞開loadclass方法,核心先找到目前類的類加載器目錄下是否有該Spi機制對應的配置檔案,如果沒有的情況下則不會進行初始化該類,會報錯。

10.SPI機制介紹

Spi機制加載第三方擴充的Jar包類初始化,對我們接口的子類實作初始化。

例如:java-JDBC 使用mysql驅動Jar包(初始化Driver類)、dubbo中RPC調用的時候。

SPI命名規範:

檔案夾命名:存在在項目中 Resoucres 建立META-INF.services

檔案命名:必須是接口類的完全限定名稱(需要初始化類的接口名稱)

類加載器與雙親委派機制

JVM 虛拟機記憶體空間圖: