Classloader的雙親委託機制(轉)

JVM自帶的ClassLoader類

JDK中提供了三個ClassLoader,根據層級從高到低爲:

Bootstrap ClassLoader,主要加載JVM自身工作需要的類。
Extension ClassLoader,主要加載%JAVA_HOME%\lib\ext目錄下的庫類。
Application ClassLoader,主要加載Classpath指定的庫類,一般情況下這是程序中的默認類加載器,也是ClassLoader.getSystemClassLoader() 的返回值。(這裏的Classpath默認指的是環境變量中配置的Classpath,但是可以在執行Java命令的時候使用-cp 參數來修改當前程序使用的Classpath)
這裏寫圖片描述

什麼是雙親委託模型
JVM加載類的實現方式,我們稱爲 雙親委託模型:

如果一個類加載器收到了類加載的請求,他首先不會自己去嘗試加載這個類,而是把這個請求委託給自己的父加載器,每一層的類加載器都是如此,因此所有的類加載請求最終都應該傳送到頂層的Bootstrap ClassLoader中,只有當父加載器反饋自己無法完成加載請求時,子加載器纔會嘗試自己加載。

雙親委託模型加載類的過程
我們用一張簡單的圖片來描述 “使用自定義ClassLoader加載一個類的過程”:
這裏寫圖片描述

自定義ClassLoader向自己的上層(Application ClassLoader)請求
Application ClassLoader繼續向上層(Extension ClassLoader)請求
Extension ClassLoader繼續向上層(Bootstrap ClassLoader)請求
Bootstrap ClassLoader是最上層類加載器,所以它嘗試在自己的路徑中查找要加載類,如果查找到了就加載類,否則向下層(Extension ClassLoader)反饋自己無法加載類。
Extension ClassLoader從自己的路徑中尋找要加載類,找到則加載,找不到則繼續向下返回。
Application ClassLoader從自己的路徑中尋找要加載類,找到則加載,找不到則繼續向下返回。
自定義ClassLoader從自己的路徑中尋找要加載類,找到則加載。由於類加載請求是自定義ClassLoader發起的,所以當它自己也找不到要加載的類時會終止加載並拋出
ClassNotFoundException。
爲什麼要用雙親委託模型
雙親委託模型的重要用途是爲了解決類載入過程中的安全性問題。

假設有一個開發者自己編寫了一個名爲java.lang.Object的類,想借此欺騙JVM。現在他要使用自定義ClassLoader來加載自己編寫的java.lang.Object類。然而幸運的是,雙親委託模型不會讓他成功。因爲JVM會優先在Bootstrap ClassLoader的路徑下找到java.lang.Object類,並載入它。

Java的類加載是否一定遵循雙親委託模型

這個答案是否定的。
雙親委託模型只是JDK提供的ClassLoader類的實現方式。
在實際開發中,我們可以通過自定義ClassLoader,並重寫父類的loadClass方法,來打破這一機制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章