在瞭解類加載機制時,發現網上大部分文章還停留在tomcat6,甚至tomcat5。
Tomcat8 和 Tomcat6比較大的區別是 :
- Tomcat8可以通過配置 <Loader delegate="true"/>不打破雙親委託
- 類的加載順序略不同
概述
在 Java 環境中,類加載器的佈局結構是一種父子樹的形式。通常,類加載器被請求加載一個特定的類或資源時,它會先把這一請求委託給它的父類加載器,只有(一個或多個)父類加載器無法找到請求的類或資源時,它纔開始查看自身的倉庫。
Web應用程序類加載器的模型與此略有不同,如下所述,但主要原則是相同的。
類加載器定義
Bootstrap
加載JVM啓動所需的類和系統擴展目錄($JAVA_HOME/jre/lib/ext)裏 JAR 文件中的類
System
加載tomcat啓動的類
Common
加載對Tomcat內部類和所有Web應用程序都可見的其他類 所有應用共享
JAR文件 $CATALINA_HOME/lib
JAR文件 $CATALINA_BASE/lib
WebappX
爲部署在單個Tomcat實例中的每個Web應用程序創建一個類加載器 加載WEB-INF/classes和WEB-INF/lib的jar中的類 應用私有
查找順序
Bootstrap
|
System
|
Common
/ \
Webapp1 Webapp2 ...
Tomcat打破了雙親委派順序
當某個請求想從 Web 應用的 WebappX 類加載器中加載類時,該類加載器會先查看自己的倉庫,而不是預先進行委託處理
Tomcat8
- JVM 的 Bootstrap 類
- Web 應用的 /WEB-INF/classes 類
- Web 應用的 /WEB-INF/lib/.jar 類*
- System 類加載器的類
- Common 類加載器的類
例:
在 /WEB-INF/classes中有一個應用內部自定義的FileUpload類, Common 中也有一個共享的FileUpload類。
Tomcat8加載順序:
- 在加載時,先不進行委託,則每個應用會加載自己的類(2/3 Web加載器)
- 加載不到時委託到再上層Common,Common再委託至System,
- 4 System加載到就返回,加載不到再讓Common處理
- 5 Common加載到就返回,加載不到拋出異常
問題:
順序1哪去了?爲什麼不再委託至Bootstrap 呢?
主要是爲了防止一些基礎類會被web中的類覆蓋
如果web自定義一個Object類呢?首先查找web加載器,就會出問題了。
所以在加載時最先交給Bootstrap加載器加載。
遵循雙親委託
如果 Web 應用類加載器配置有 <Loader delegate="true"/>,表示遵從雙親委託機制,同JVM,則加載順序變爲:
- JVM 的 Bootstrap 類
- System 類加載器的類
- Common 類加載器的類
- Web 應用的 /WEB-INF/classes 類
- Web 應用的 /WEB-INF/lib/*.jar 類
例:
在 /WEB-INF/classes中有一個應用內部自定義的FileUpload類, Common 中也有一個共享的FileUpload類,
順序:
嚴格按照雙親委派模型進行
想學習分佈式、微服務、JVM、多線程、架構、java、python的童鞋,千萬不要掃碼,否則後果自負~
林老師帶你學編程:https://wolzq.com