首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

How Tomcat Works 讀書筆記第八章:類載入器架構與 WebappClassLoader 深度解析

     編輯:C++ 入門

How Tomcat Works 讀書筆記第八章:類載入器架構與 WebappClassLoader 深度解析

核心概念釐清

  • 倉庫:類載入器搜索類文件的目錄
  • 資源:類載入器中的 DirContext 對象,文件根路徑指向上下文的文件根路徑
  • 載入器 vs 類載入器:Tomcat 中的「載入器」是指 Web 應用程序載入器(實現 Loader 接口),內部包含一個類載入器(默認 WebappClassLoader)

Tomcat 使用自定義載入器的三大原因

  1. 指定特定的類加載規則(如 Servlet 只能訪問 WEB-INF/classes 和 WEB-INF/lib)
  2. 緩存已加載的類,提升性能
  3. 支持類的預加載與自動重載(熱部署)

Loader 接口核心方法

public interface Loader {
    ClassLoader getClassLoader();           // 獲取內部類載入器
    Container getContainer();               // 關聯的容器
    void setContainer(Container container);
    boolean getDelegate();                  // 是否委派給父類載入器
    void setDelegate(boolean delegate);
    boolean getReloadable();                // 是否支持自動重載
    void setReloadable(boolean reloadable);
    void addRepository(String repository);  // 添加倉庫路徑
    String[] findRepositories();
    boolean modified();                     // 類文件是否被修改
    // ... PropertyChangeListener 相關方法
}

啟用自動重載配置

在 server.xml 中配置 Context 元素:

<Context debug="0" docBase="myApp" path="/myApp" reloadable="true" />

WebappLoader 類啟動流程

WebappLoader.start() 執行以下關鍵步驟:

  1. 創建類載入器:實例化 WebappClassLoader,可通過 setLoaderClass 自定義(需繼承 WebappClassLoader)
  2. 設置倉庫:調用 setRepositories 添加 WEB-INF/classes 和 WEB-INF/lib
  3. 設置類路徑:供 Jasper JSP 編譯器使用
  4. 設置訪問權限:限制類載入器只能訪問允許的目錄
  5. 啟動後台線程:執行 run() 方法,定期檢查類文件修改(間隔 checkInterval 秒),檢測到變更調用 container.reload()

後台重載線程實現

public void run() {
    while (!threadDone) {
        threadSleep();  // 休眠 checkInterval 秒
        if (!started) break;
        try {
            if (!classLoader.modified()) continue;  // 無變更繼續
        } catch (Exception e) { log(...); continue; }
        notifyContext();  // 觸發重載
        break;
    }
}

private void notifyContext() {
    new Thread(new WebappContextNotifier()).start();  // 新線程避免阻塞
}

class WebappContextNotifier implements Runnable {
    public void run() { ((Context) container).reload(); }
}

WebappClassLoader 核心特性

1. 安全限制 - 禁止加載特定類/包

// 禁止加載的類
private static final String[] triggers = {
    "javax.servlet.Servlet"
};

// 禁止委派給系統載入器的包
private static final String[] packageTriggers = {
    "javax", "org.xml.sax", "org.w3c.dom",
    "org.apache.xerces", "org.apache.xalan"
};

2. 兩級緩存機制

  • 本地緩存:WebappClassLoader 實例管理的 HashMap resourceEntries
  • 父類緩存:java.lang.ClassLoader 維護的 Vector 緩存

3. ResourceEntry 資源條目結構

public class ResourceEntry {
    public long lastModified = -1;      // 最後修改時間
    public byte[] binaryContent = null; // 類文件字節碼
    public Class loadedClass = null;    // 已加載的 Class 對象
    public URL source = null;           // 來源 URL
    public URL codeBase = null;         // 代碼庫 URL
    public Manifest manifest = null;    // 清單信息
    public Certificate[] certificates = null; // 證書
}

未找到的資源存放在 notFoundResources 中,避免重複查找。

UML 類圖關係

Loader 接口與實現類 UML 圖

參考資源

OSChina 相關博客

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved