Tomcat類加載機制

Tomcat中的類加載策略和JDK中的委託模型略有不同。Tomcat Server在啓動的時候將構造一個ClassLoader樹,以保證模塊的類庫是私有的,ClassLoader結構如下:
             Bootstrap
                   |
              System
                  |
            Common
          /                \
 Catalina          Shared
                      /  ... ...    \
            webapp1        webappN

各個類加載器的作用描述如下:
1)Bootstrap ClassLoader: 負責加載由虛擬機提供的基本運行時類和系統擴展目錄($JAVA_HOME/jre/lib/ext)下的JAR包;
2)System ClassLoader: 通常這個加載器用來加載CLASSPATH環境變量中指定的類,但在Tomcat5的標準啓動腳本($CATALINA_HOME/bin/catalina.sh或%CATALINA_HOME%/bin/catalina.bat)中改變了它的行爲,它只加載下面的類:
$CATALINA_HOME/bin/bootstrap.jar    // Contains the main() method that is used to initialize the Tomcat 5 server, and the class loader implementation classes it depends on.
$JAVA_HOME/lib/tools.jar // Contains the "javac" compiler used to convert JSP pages into servlet classes.
$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 implementation.

Common ClassLoader:它負責加載Tomcat本身和所有的web應用都能看到的類。通常,應用的類不應該由他加載。

$CATALINA_HOME/common/classes,$CATALINA_HOME/commons/endorsed和$CATALINA_HOME/common/lib下的類都由這個加載器加載。缺省的,包括: 
ant.jar - Apache Ant.
commons-collection.jar  // Jakarta commons collection.
commons-dbcp.jar // Jakarta commons DBCP, providing a JDBC connection pool to web applications.
commons-el.jar // Jakarta commons el, implementing the expression language used by Jasper.
commons-pool.jar // Jakarta commons pool.
jasper-compiler.jar // The JSP 2.0 compiler.
jasper-runtime.jar // The JSP 2.0 runtime.
jsp-api.jar // The JSP 2.0 API.
naming-common.jar // The JNDI implementation used by Tomcat 5 to represent in-memory naming contexts.
naming-factory.jar // The JNDI implementation used by Tomcat 5 to resolve references to enterprise resources (EJB, connection pools).
naming-resources.jar // The specialized JNDI naming context implementation used to represent the static resources of a web application.
servlet-api.jar // The Servlet and JSP API classes.
xerces.jar // The XML parser that is visible by default to Tomcat internal classes and to web applications.
xml-apis.jar

Catalina ClassLoader: 用來加載實現Tomcat自己需要的類。由它加載的類對web應用都是不可見的。$CATALINA_HOME/server/classes,$CATALINA_HOME/server/lib,都由這個加載器加載。缺省的,包括:

catalina.jar - Implementation of the Catalina servlet container portion of Tomcat 5.

jakarta-regexp-X.Y.jar - The binary distribution of the Jakarta Regexp regular expression processing library, used in the implementation of request filters.

servlets-xxxxx.jar - The classes associated with each internal servlet that provides part of Tomcat's functionality. These are separated so that they can be completely removed if the corresponding service is not required, or they can be subject to specialized security manager permissions.

tomcat-coyote.jar - Coyote connector for Tomcat 5.

tomcat-http11.jar - Standalone Java HTTP/1.1 connector.

tomcat-jk2.jar - Classes for the Java portion of the JK 2 web server connector, which allows Tomcat to run behind web servers such as Apache and iPlanet iAS and iWS.

tomcat-util.jar - Utility classes required by some Tomcat connectors.
Shared ClassLoader:被所有的web應用共享的類和資源由這個加載器加載。$CATALINA_BASE/shared/classed,$CATALINA_BASE/shared/lib,都由這個加載器加載。
WebappX ClassLoader:對每個Tomcat裏的web應用都創建一個加載器,web應用下的WEB-INF/classes,WEB-INF/lib,都由這個加載器加載,由它所加載的類對其他的web應用是不可見的。
web應用的加載器(WebappX)和JDK的委託模型略有不同,這是根據Servlet2.3規範做出的。當WebappX被請求加載一個類時,它首先嚐試自己加載,而不是先委託給它的父加載器加載,如果無法加載該類,則委託它的父加載器加載。但是,對於下面的類,仍然要先委託給父加載器:

Classes which are part of the JRE base classes cannot be overriden. For some classes (such as the XML parser components in JDK 1.4+), the JDK 1.4 endorsed feature can be used (see the common classloader definition above). In addition, for the following class patterns, the classloader will always delegate first (and load the class itself if no parent classloader loads it):
javax.*
org.xml.sax.*
org.w3c.dom.*
org.apache.xerces.*
org.apache.xalan.*
 Last, any JAR containing servlet API classes will be ignored by the classloader.

Tomcat中其他的加載器都是遵循委託模型的。
最後,以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/lib/*.jar
$CATALINA_BASE/shared/classes
$CATALINA_BASE/shared/lib/*.jar

結論

對於只用於某一個web應用的類或資源,放在這個web應用下的/WEB-INF/classes目錄下,如果是JAR,就放在這個web應用下的WEB-INF/lib目錄下。
     對於讓所有的web應用共享的類或資源,放在$CATALINA_BASE/shared/classes目錄下,如果是JAR,就放在$CATALINA_BASE/shared/lib目錄下。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章