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.自定義類加載器: 也就是使用者自己定義的類加載器
類加載器執行順序圖:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SN0cTMzUzM3MWMyEjM3ATOyYzX0ETOzQTM3IzLcVDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
類加載器分類職能圖:
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 虛拟機記憶體空間圖: