Tomcat 7 類加載器是如何實現的

Tomcat 7 類加載器是如何實現的

XML分析器和Java
在安全管理器下運行
高級配置
概觀

概述

與許多服務器應用程序一樣,Tomcat安裝了各種類加載器(即實現的類java.lang.ClassLoader),以允許容器的不同部分和容器上運行的Web應用程序訪問可用類和資源的不同存儲庫。此機制用於提供Servlet規範2.4版中定義的功能 - 特別是9.4和9.6節。

在Java環境中,類加載器排列在父子樹中。通常,當要求類加載器加載特定的類或資源時,它首先將請求委託給父類加載器,然後僅在父類加載器找不到所請求的類或資源時查找它自己的存儲庫。 。請注意,Web應用程序類加載器的模型與此略有不同,如下所述,但主要原則是相同的。

當Tomcat啓動時,它會創建一組類加載器,這些加載器被組織成以下父子關係,其中父類加載器位於子類加載器之上:

      Bootstrap
          |
       System
          |
       Common
       /     \
  Webapp1   Webapp2 ...

這些類加載器的特徵,包括它們可見的類和資源的來源,將在下一節中詳細討論。

類加載器定義

如上圖所示,Tomcat在初始化時創建以下類加載器:

    • Bootstrap - 此類加載器包含Java虛擬機提供的基本運行時類,以及System Extensions目錄($JAVA_HOME/jre/lib/ext)中存在的JAR文件中的任何類。 注意:一些JVM可能將其實現爲多個類加載器,或者它可能根本不可見(作爲類加載器)。
    • System - 此類加載器通常從CLASSPATH環境變量的內容初始化。Tomcat內部類和Web應用程序都可以看到所有這些類。但是,標準的Tomcat啓動腳本($CATALINA_HOME/bin/catalina.sh或 %CATALINA_HOME%bincatalina.bat)完全忽略CLASSPATH環境變量本身的內容,而是從以下存儲庫構建System類加載器:
    1. $CATALINA_HOME/bin/bootstrap.jar - 包含用於初始化 Tomcat 服務器的main() 方法,以及它依賴的類加載器實現類。
    2. $CATALINA_BASE/bin/tomcat-juli.jar 或 $CATALINA_HOME/bin/tomcat-juli.jar - 記錄實現類。其中包括java.util.loggingAPI 的增強類 ,稱爲Tomcat JULI,以及Tomcat內部使用的Apache Commons Logging庫的軟件包重命名副本。有關詳細信息,請參閱日誌記錄

    如果tomcat-juli.jar是出現在 $CATALINA_BASE/bin 中,它被用來代替 $CATALINA_HOME/bin 中的那一個。它在某些日誌記錄配置中很有用

    1. $CATALINA_HOME/bin/commons-daemon.jar - 來自Apache Commons Daemon項目的類。這個JAR文件不存在於CLASSPATH 由腳本catalina.bat|.sh 構建,但是從bootstrap.jar的清單文件中引用。

      • Common - 此類加載器包含對Tomcat內部類和所有Web應用程序都可見的其他類。

    通常情況下,應用類應該不 放在這裏。此類由common.loader加載器搜索的位置$CATALINA_BASE/conf/catalina.properties 中的屬性定義。默認設置將按列出的順序搜索以下位置:

    1. 解壓縮的類和資源 $CATALINA_BASE/lib
    2. JAR文件 $CATALINA_BASE/lib
    3. 解壓縮的類和資源 $CATALINA_HOME/lib
    4. JAR文件 $CATALINA_HOME/lib

    默認情況下,這包括以下內容:

    annotations-api.jar - JavaEE註釋類。
    catalina.jar - Tomcat的Catalina servlet容器部分的實現。
    catalina-ant.jar - Tomcat Catalina Ant任務。
    catalina-ha.jar - 高可用性包。
    catalina-tribes.jar - 羣組通信包。
    ecj - * .jar - Eclipse JDT Java編譯器。
    el-api.jar - EL 2.2 API。
    jasper.jar - Tomcat Jasper JSP編譯器和運行時。
    jasper-el.jar - Tomcat Jasper EL實現。
    jsp-api.jar - JSP 2.2 API。
    servlet-api.jar - Servlet 3.0 API。
    tomcat-api.jar - Tomcat定義的幾個接口。
    tomcat-coyote.jar - Tomcat連接器和實用程序類。
    tomcat-dbcp.jar - 基於包重命名的Apache Commons Pool和Apache Commons DBCP 1.x的數據庫連接池實現。
    tomcat-i18n - **。jar - 包含其他語言資源包的可選JAR。由於默認捆綁包也包含在每個單獨的JAR中,因此如果不需要消息的國際化,則可以安全地刪除它們。
    tomcat-jdbc.jar - 另一種數據庫連接池實現,稱爲Tomcat JDBC池。有關詳細信息,請參閱 文檔
    tomcat-util.jar - Apache Tomcat的各種組件使用的公共類。
    tomcat7-websocket.jar - WebSocket 1.1實現
    websocket-api.jar - WebSocket 1.1 API
    WebappX - 爲部署在單個Tomcat實例中的每個Web應用程序創建一個類加載器。/WEB-INF/classesWeb應用程序目錄中的所有解壓縮的類和資源,以及Web應用程序/WEB-INF/lib目錄下的JAR文件中的類和資源,都對此Web應用程序可見,但對其他應用程序不可見。

    如上所述,Web應用程序類加載器與默認Java委託模型不同(根據Servlet規範2.4版,第9.7.2節Web應用程序類加載器中的建議)。當加載從Web應用程序的一個類的請求WebappX被處理的類加載器,這個類加載器會在本地資源庫第一而不是在尋找之前委託。也有例外。作爲JRE基類的一部分的類不能被覆蓋。對於某些類(例如J2SE 1.4+中的XML解析器組件),Java認可的功能可以用於Java 8.最後,類加載器將明確忽略包含Servlet API類的任何JAR文件 - 不包括此類Web應用程序中的JAR。Tomcat中的所有其他類加載器都遵循通常的委託模式。

    因此,從Web應用程序的角度來看,類或資源加載按以下順序查找以下存儲庫:

    1. JVM的Bootstrap類
    2. /WEB-INF/classes 您的Web應用程序的類
    3. /WEB-INF/lib/*.jar 您的Web應用程序Jar 包
    4. System 類加載器類(如上所述)
    5. Common 類加載器類(如上所述)

    如果配置了Web應用程序類加載器 , <Loader delegate="true"/> 則清單順序變爲:

    1. JVM的Bootstrap類
    2. System 類加載器類(如上所述)
    3. Common 的類加載器類(如上所述)
    4. /WEB-INF/classes 您的Web應用程序的類
    5. /WEB-INF/lib/*.jar 您的Web應用程序的Jar 包

    XML分析器和Java

    從Java 1.4開始,JRE中包含一個JAXP API和一個XML解析器。這會對希望使用自己的XML解析器的應用程序產生影響。

    在舊版本的Tomcat中,您只需替換Tomcat庫目錄中的XML解析器即可更改所有Web應用程序使用的解析器。但是,當您運行現代版本的Java時,此技術將無效,因爲通常的類加載器委派過程將始終在JDK中選擇優先於此實現的實現。

    Java支持一種稱爲“支持標準覆蓋機制”的機制,以允許替換在JCP外部創建的API(即來自W3C的DOM和SAX)。它還可用於更新XML解析器實現。有關更多信息,請參閱: http: //docs.oracle.com/javase/1.5.0/docs/guide/standards/index.html。

    Tomcat通過-Djava.endorsed.dirs=$JAVA_ENDORSED_DIRS 在啓動容器的命令行中包含系統屬性設置來利用此機制 。此選項的默認值爲 $CATALINA_HOME/endorsed。默認情況下不會創建此已簽名的目錄。請注意,Java 9不再支持已認可的功能,並且只有在目錄$CATALINA_HOME/endorsed 存在或 JAVA_ENDORSED_DIRS 已設置變量 時纔會設置上述系統屬性。

    請注意,覆蓋任何JRE組件都存在風險。如果覆蓋組件未提供100%兼容的API(例如,Xerces提供的API與JRE提供的XML API不完全兼容),則存在Tomcat和/或部署的應用程序將出現錯誤的風險。

    在安全管理器下運行

    在安全管理器下運行時,允許加載類的位置也取決於策略文件的內容。有關詳細信息,請參閱安全管理器HOW-TO。

    高級配置

    還可以配置更復雜的類加載器層次結構。見下圖。默認情況下, 未定義 Server 和 Shared 類加載器,並使用上面顯示的簡化層次結構。可以通過定義 server.loader 和/或 shared.loader 屬性的 值來使用這種更復雜的層次結構 conf/catalina.properties。

      Bootstrap
          |
        System
          |
        Common
         /  \
    Server  Shared
             /  \
       Webapp1  Webapp2 ...
    

    該服務器類加載器是唯一到Tomcat內部可見,並且是Web應用程序完全不可見。

    所述共享類加載器是將所有的web應用程序可見,並且可以在所有的web應用程序被用來共享代碼。但是,對此共享代碼的任何更新都需要重新啓動Tomcat。

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