天天看點

Tomcat ClassLoader機制介紹

本文旨在介紹JVM的類加載機制;同時分析Tomcat不能采用預設的加載機制的原因,并對其加載機制做了介紹。

1、JVM中的類加載機制

在Java2之後的版本中,類的加載采用的是一種稱為雙親委派的代理模型:也就是說目前ClassLoader在加載類前,先委派給雙親去加載類;

在有雙親委派模式的情況下,啟動類裝載器可以搶在标準擴充類裝載器之前去裝載類,而标準擴充類裝載器可以搶在系統類裝載器之前去裝載那個類,類路徑類裝載器又可以搶在使用者自定義類裝載器之前去裝載它,用這種方法,類裝載器的體系結構就可以防止不可靠的代碼用它們自己的版本來替代可信任的類。

Bootstrap class loader:最頂級的class loader,采用native code實作,是JVM的一部分;它負責加載核心的Java包,如java.lang.*、java.uti.*等; 這些類位于$JAVA_HOME/jre/lib/rt.jar;

Extension class loader:擴充的class loader,加載位于$JAVA_HOME/jre/lib/ext目錄下的擴充jar;

System class loader:系統class loader,加載$CLASSPATH下的目錄和jar;它負責加載應用程式主函數類;

2、Tomcat中的類加載

當一個Servlet直接代理類裝載請求給System class loader,則一個Context會加載其它Context下的類;是以每個Context必須要有自己的類裝載器,用于裝載WEB-INF/classes和WEB-INF/lib下的類;

當Context需要裝載類時,先試着裝載位于WEB-INF/classes和WEB-INF/lib下的類;如果裝載失敗,則再代理給上級class loader;

Common class loader:負責裝載$CATALINA_HOME/common目錄下的所有類和jar包,詳細的配置可參考$CATALINA_HOME/conf/catalina.properties檔案中的common.loader配置;該class loader裝載的類對于Server class loader和Webapp class loader是可見的;Common class loader在Tomcat啟動時建立,其parent class loader是System class loader;

Server class loader:負責裝載Tomcat的核心類,位于$CATALINE_HOME/server目錄下的所有類和jar,可由catalina.propreties中的server.loader配置指定;它在Tomcat啟動時被建立,其parent loader是Common class loader;

Shared class loader:負責裝載web app公用的類,可以使用者通過catalina.properties檔案中的shared.loader屬性來指定;它在Tomcat啟動時被建立,其parent loader也是Common class loader;

Webapp class loader:這個比較特殊,它隻負責加載各自app中WEB-INF/classes以及WEB-INF/lib下的類;其parent loader雖然是Shared class loader,但其加載政策和預設的類加載機制不太一樣;

3、Webapp class loader

其類加載政策如下:

1) 先看之前有沒有加載過此類,如果加載過,直接從緩存中取出Class;

2) 如果之前沒有加載過,則直接委托System class loader加載(防止應用程式替換信任類),而System class loader會按預設的雙親委派模式加載;

3) 如果System class loader加載失敗,則試圖在目前應用程式的WEB-INF/classes和WEB-INF/lib目錄下加載(對于一些特殊的類,可能會先委托給Shared class loader加載);

4) 如果自己加載失敗,則最後委托給Shared class loader加載;

簡單畫了一下加載順序,可以參考一下:若轉載請注明出處!若有疑問,請回複交流!