http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html
Tomcat Class Loader HOW-TO
當Tomcat5啟動以后,它創建一系列類加載器。這些類加載器以父子關系組織在一起,父類加載器在子類加載器的上面:
????? Bootstrap
????????? |
?????? System
????????? |
?????? Common
????? /????? \
Catalina?? Shared
?????????????????? ? /?? \
??????? Webapp1? Webapp2 ...
這些類加載器所扮演的角色,以及它們可以見到的類和資源的規則如下:
如上圖所示,Tomcat5 在初始化的時候創建如下類加載器:
Bootstrap - 這個類加載器可以加載Java虛擬機的運行時基礎類,以及在系統擴展目錄($JAVA_HOME/jre/lib/ext
)中的所有Jar包中的類。注意-一些JVM可能用多個類加載器來實現它,或者它是根本不能被看見的。
System - 這個類加載器一般可以加載CLASSPATH環境變量的內容。所有這個類對于Tomcat內部的類和web應用程序的都是可見的。盡管如此,標準的Tomcat5啟動腳本($CATALINA_HOME/bin/catalina.sh
?或 %CATALINA_HOME%\bin\catalina.bat
)都會忽略CLASSPATH環境變量,取而代之的是從如下倉庫加載:
- $CATALINA_HOME/bin/bootstrap.jar - 包含Tomcat5 服務器初始化的main()方法,以及所需的類加載器的實現類。
- $JAVA_HOME/lib/tools.jar - 包括把JSP頁面編譯成Serlet類所需的"javac"編譯器.
- $CATALINA_HOME/bin/commons-logging-api.jar - Jakarta commons logging API.
- $CATALINA_HOME/bin/commons-daemon.jar - Jakarta commons daemon API.
- jmx.jar - The JMX 1.2 實現.
Common - 這個類加載器可以使一些附加的類對于Tomcat內部的類和web應用程序可見。正常情況下,應用程序不應該替換它。所有$CATALINA_HOME/common/classes目錄下的未打包類和資源,以及$CATALINA_HOME/commons/endorsed、$CATALINA_HOME/commons/i18n、$CATALINA_HOME/common/lib目錄下的Jar包中的類和資源都是這個類加載器的加載對象。默認情況,包括如下內容:?????????
- commons-el.jar - Jakarta commons el, Jasper用的EL表達式實現
- jasper-compiler.jar - The JSP 2.0 編譯器.
- jasper-compiler-jdt.jar - The Eclipse JDT Java 編譯器.
- jasper-runtime.jar - The JSP 2.0 運行庫.
- jsp-api.jar - The JSP 2.0 API.
- naming-common.jar - Tomcat5的JNDI 實現,用于內存命名環境
- naming-factory.jar - Tomcat5的JNDI 實現,用于企業級資源引用(EJB, connection pools).
- naming-factory-dbcp.jar - Jakarta commons DBCP, 為Web應用程序提供JDBC連接池。這個類已經從默認的org.apache.commons包中移出。
- naming-java.jar -? java命名空間處理器.
- naming-resources.jar - The specialized JNDI naming context implementation used to represent the static resources of a web application. This is not related to the support of the J2EE ENC, and cannot be removed.
- servlet-api.jar - The Servlet 2.4 API.
- tomcat-i18n-**.jar - Optional JARs containing resource bundles for other languages. As default bundles are also included in each individual JAR, they can be safely removed if no internationalization of messages is needed.
Catalina - 這個類加載器主要加載Tomcat5自己所需要的類和資源。這些類和資源對于Web應用程序是完全不可見的。在$CATALINA_HOME/server/classes目錄下的所有類和資源,$CATALINA_HOME/server/lib下的所有Jar包中類和資源是這個類加載器的加載對象。默認情況,包括個如下內容:
- catalina.jar - Tomcat5中Catalina Servlet容器的實現部分。
- catalina-ant.jar - 在管理web應用程序時要用倒的一些Ant任務。
- catalina-optional.jar - 一些Catalina可選組件。
- commons-modeler.jar - Tomcat通過JMX暴露其內部對象是用的一些MBean實現。
- servlets-xxxxx.jar - 這些類同內部的Servlet一起提供Tomcat的部分功能,它們都是獨立的,所以如果不需要相應的服務可以將其刪除。或者它們可以從屬于特定的安全管理器。
- tomcat-coyote.jar - Coyote API.。
- tomcat-http.jar - 標準的Java HTTP/1.1 連接器.。
- tomcat-ajp.jar -?
AJP
web?服務器的連接器,一般用于Apache,iPlanet iAS和 iWS.。
- tomcat-util.jar - Tomcat連接器需要的工具類。
Shared - 這個類加載器用于把一些類和資源共享給所有的web應用程序。(除非Tomcat內部的類也需要訪問這些類,在這種情況下你應該把它們放在Common類加載能加載的地方). 在$CATALINA_BASE/shared/classes目錄下的所有未打包類和資源,以及$CATALINA_BASE/shared/lib目錄下的所有Jar包中的類和資源可以被其加載。如果通過$CATALINA_BASE環境變量來從同一個tomcat程序運行了多個在實例,那么這個類加載器的倉庫是相對于$CATALINA_BASE而不是$CATALINA_HOME。?
WebappX - 系統會為部署在一個Tomcat實例中的每個應用程序創建一個這樣的類加載器,它們為所屬的應用程序加載類。所有你的web應用程序包的/WEB-INF/classes目錄下的類和資源,以及
/WEB-INF/lib 目錄下的所有Jar包中的類和資源是這個類的加載對象。這些類和資源僅對這個應用程序可見,并且這個應用程序也看不見其他應用程序的類和資源。
就像上面所描述的,web應用程序的類加載的加載流程與默認的Java 2的類記載托管模型是不一樣的。當有一個請求需要應用程序的WebappX 類加載器加載一個類的時候,這個類加載器是首先到自己的倉庫中查找,而不是先交給上面的類加載器查找。這里有一些例外。JRE的基礎類是不能被覆蓋的。對于其他一些類(如J2SE 1.4+中的XML解析器組件),可以使用J2SE1.4的簽名特性。最后任何包括servlet API類的Jar包會被忽略。Tomcat5中的其他的類加載器使用正常托管模式。
這樣在一個web應用程序中,類和資源的加載順序是這樣:
- Bootstrap classes of your JVM
- System class loader classses (described above)
-
/WEB-INF/classes of your web application
-
/WEB-INF/lib/*.jar of your web application
-
$CATALINA_HOME/common/classes
-
$CATALINA_HOME/common/endorsed/*.jar
-
$CATALINA_HOME/common/i18n/*.jar
-
$CATALINA_HOME/common/lib/*.jar
-
$CATALINA_BASE/shared/classes
-
$CATALINA_BASE/shared/lib/*.jar