您好,登錄后才能下訂單哦!
本篇內容介紹了“何為雙親委派”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
雙親委派機制
??雙親委派機制是指當一個類加載器收到一個類加載請求時,該類加載器首先會把請求委派給父類加載器。每個類加載器都是如此(遞歸的去查找),只有在父類加載器在自己的搜索范圍內找不到指定類時,子類加載器才會嘗試自己去加載。
顯然,在介紹雙親委派機制的時候,不得不提ClassLoader。再說ClassLoader之前,我們得先了解下Java的基本知識。
Java是運行在Java的虛擬機(JVM)中的,但是它是怎么就運行在JVM中了呢?我們在IDE中編寫的Java源代碼被編譯器編譯成.class
的字節碼文件。然后由我們的ClassLoader
負責將這些class文件加載到JVM
中去執行。
JVM中提供了三層的ClassLoader:
Bootstrap ClassLoader(啟動類加載器):主要負責加載核心的類庫(java.lang.*等),構造Extension ClassLoader
和Application ClassLoader
。
Extension ClassLoader(擴展類加載器):主要負責加載jre/lib/ext
目錄下的一些擴展的jar。
Application ClassLoader(應用程序類加載器):主要負責加載應用程序
的主函數類。
最后一個CustomClassLoader(用戶自定義類加載器) 是java
編寫,用戶自定義的類加載器,可加載指定路徑的class文件
。
那如果有一個Hello.class
文件是如何被加載到JVM中的呢?
我們簡單看一下源碼
protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// 首先檢查這個classsh是否已經加載過了Class<?> c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {// c==null表示沒有加載,如果有父類的加載器則讓父類加載器加載if (parent != null) {c = parent.loadClass(name, false);} else {//如果父類的加載器為空 則說明遞歸到bootStrapClassloader了//bootStrapClassloader比較特殊無法通過get獲取c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {}if (c == null) {//如果bootstrapClassLoader 仍然沒有加載過,則遞歸回來,嘗試自己去加載classlong t1 = System.nanoTime();c = findClass(name);sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}}
不考慮我們自定義類加載器,首先會在AppClassLoader中檢查是否加載過,如果有那就無需再加載了。如果沒有,那么會拿到父加載器,然后調用父加載器的loadClass方法。父類中同理會先檢查自己是否已經加載過,如果沒有再往上。注意這個過程,直到到達Bootstrap ClassLoader之前,都是沒有哪個加載器自己選擇加載的。如果父加載器無法加載,會下沉到子加載器去加載,一直到最底層(其實就是遞歸查找過程),如果沒有任何加載器能加載,就會拋出ClassNotFoundException
。
于是,我們就可以很好的總結雙親委派機制的工作流程了:
1、當Application ClassLoader
收到一個類加載請求時,他首先不會自己去嘗試加載這個類,而是將這個請求委派給父類加載器Extension ClassLoader
去完成。
2、當Extension ClassLoader
收到一個類加載請求時,他首先也不會自己去嘗試加載這個類,而是將請求委派給父類加載器Bootstrap ClassLoader
去完成。
3、如果Bootstrap ClassLoader
加載失敗(在<JAVA_HOME>\lib中未找到所需類),就會讓Extension ClassLoader
嘗試加載。
4、如果Extension ClassLoader
也加載失敗,就會使用Application ClassLoader
加載。
5、如果Application ClassLoader
也加載失敗,就會使用Custom ClassLoader
(用戶自定義加載器)去嘗試加載。
6、如果均加載失敗,就會拋出ClassNotFoundException
異常。
雙親委派機制的作用
1、防止重復加載同一個.class
。通過委托去向上面問一問,加載過了,就不用再加載一遍。保證數據安全。
2、保證核心.class
不能被篡改。通過委托方式,不會去篡改核心.class
,即使篡改也不會去加載,即使加載也不會是同一個.class
對象了。不同的加載器加載同一個.class
也不是同一個Class對象。這樣保證了Class執行安全。
舉個栗子:如果有人想替換系統級別的類:String.java
。篡改它的實現,但是在這種機制下這些系統的類已經被Bootstrap ClassLoader
加載過了,所以并不會再去加載,從一定程度上防止了危險代碼的植入。
“何為雙親委派”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。