雙親委派機制
- 雙親委派機制
- Tomcat打破雙親委派機制
雙親委派機制
雙親委派機制,加載某個類時會先委托父加載器尋找目標類,找不到再委托上層父加載器加載,如果所有父加載器在自己的加載類路徑下都找不到目標類,則在自己的類加載路徑中查找并載入目標類。
比如我們的Test類,最先會找應用程序類加載器加載,應用程序類加載器會先委托擴展類加載器加載,擴展類加載器再委托引導類加載器,頂層引導類加載器在自己的類加載路徑里找沒找到Test類,則向下加載Test類的請求,擴展類加載器 接到指令自己加載,在自己的類加載路徑里也沒找到Test類,又向下退回Test類的加載請求給應用程序類加載器,應用程序類加載器于是在自己的類加載路徑里找Test類,進行加載
注:雙親委派機制說簡單點就是,先找父親加載,不行再由兒子自己加載
應用程序類加載器AppClassLoader加載類的雙親委派機制源碼,AppClassLoader的loadClass方法最終會調用其父類ClassLoader的loadClass方法,該方法的大體邏輯如下:
首先,檢查一下指定名稱的類是否已經加載過,如果加載過了,就不需要再加載,直接返回。
如果此類沒有加載過,那么,再判斷一下是否有父加載器;如果有父加載器,則由父加載器加載(即調用parent.loadClass(name, false);).或者是調用bootstrapLoader類加載器來加載。
如果父加載器及bootstrapLoader類加載器都沒有找到指定的類,那么調用當前類加載器的findClass方法來完成類加載。
自定義類加載器示例:
自定義類加載器只需要繼承 java.lang.ClassLoader 類,該類有兩個核心方法,一個是loadClass(String, boolean),實現了雙親委派機制,還有一個方法是findClass,默認實現是空方法,所以我們自定義類加載器主要是重寫findClass方法。
Tomcat打破雙親委派機制
- 一個web容器可能需要部署多個應用程序,不同的應用程序可能會依賴同一個第三方類庫的不同版本,不能要求同一個類庫在同一個服務器只有一份,因此要保證每個應用程序的類庫都是獨立的,保證相互隔離。
- 部署在同一個web容器中相同的類庫相同的版本可以共享。否則,如果服務器有很多個應用程序,那么要有很多份相同的類庫加載進虛擬機。
- web容器也有自己依賴的類庫,不能與應用程序的類庫混淆。基于安全考慮,應該讓容器的類庫和程序的類庫隔離開來。
WebappClassLoader:各個Webapp私有的類加載器,加載路徑中的class只對當前Webapp可見,比如加載war包里相關的類,每個war包應用都有自己的WebappClassLoader,實現相互隔離,比如不同war包應用引入了不同的spring版本,這樣實現就能加載各自的spring版本;
注意:同一個JVM內,兩個相同包名和類名的類對象可以共存,因為他們的類加載器可以不一樣,所以看兩個類對象是否是同一個,除了看類的包名和類名是否都相同之外,還需要他們的類加載器也是同一個才能認為他們是同一個。
后續有詳細的再補-----------