首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Tomcat 啟動源碼深度解析(三):容器組件啟動流程與 Pipeline-Valve 機制

     編輯:Java 綜合教學

前言

承接上文,StandardService 啟動時遵循「先容器後連接器」的順序。本文聚焦容器層級的啟動流程,重點剖析 StandardEngine、StandardHost、StandardContext 的啟動鏈路,以及核心機制 Pipeline-Valve 的工作原理。

Pipeline-Valve:容器間的責任鏈

Pipeline(管道) 連接兩個容器層級,請求從父容器流向子容器時經過管道。管道上可掛載多個 Valve(閥門),攔截請求執行橫切邏輯(日誌、認證、壓縮等),類似 Servlet Filter 但作用於容器層級。

  • 每個容器擁有一個 StandardPipeline 實例
  • 每個容器有一個基礎閥門:StandardEngineValve、StandardHostValve、StandardContextValve、StandardWrapperValve
  • 閥門鏈調用順序:Valve.invoke(Request, Response) → getNext().invoke(...) → 基礎閥門 → 返回

StandardEngine:頂層容器啟動

initInternal

  • 註冊 MBean
  • 初始化 startStopExecutor(ThreadPoolExecutor),用於並行啟動子容器

startInternal 核心邏輯

protected synchronized void startInternal() throws LifecycleException {
    // 1. 啟動關聯組件:Loader、Manager、Cluster、Realm、Resources
    if (loader != null) loader.start();
    if (manager != null) manager.start();
    if (cluster != null) cluster.start();
    Realm realm = getRealmInternal();
    if (realm != null) realm.start();
    if (resources != null) resources.start();
    
    // 2. 並行啟動子容器
    Container[] children = findChildren(); // 獲取所有 StandardHost
    List<Future<Void>> results = new ArrayList<>();
    for (Container child : children) {
        results.add(startStopExecutor.submit(new StartChild(child)));
    }
    // 等待所有子容器啟動完成
    for (Future<Void> result : results) {
        result.get(); // 異常則標記失敗
    }
    
    // 3. 啟動 Pipeline(含基礎閥門 StandardEngineValve)
    if (pipeline instanceof Lifecycle) pipeline.start();
    
    // 4. 狀態變更與事件通知
    setState(LifecycleState.STARTING);
    
    // 5. 啟動後台線程:定期觸發 backgroundProcess、PERIODIC_EVENT
    threadStart();
}

關鍵點:子容器並行啟動提升啟動速度;必須等待所有 Host 啟動完成後,Connector 才能開始接收請求。

StandardHost:虛擬主機容器

職責與 StandardEngine 類似,負責並行啟動其子容器 StandardContext(Web 應用)。啟動邏輯基本一致,此處不再贅述。

StandardContext:Web 應用核心,部署與解析中樞

這是容器啟動中最複雜、最關鍵的類,負責 web.xml 解析、Servlet 部署、資源初始化等。

init 階段

  • 註冊 MBean
  • 觸發 Lifecycle.AFTER_INIT_EVENT,ContextConfig 監聽並構建解析 web.xml 的 Digester

startInternal 核心步驟

  1. 資源初始化:setResources、初始化 WebappLoader、字符集映射器、工作目錄(work/Catalina/localhost/...)
  2. 觸發 CONFIGURE_START_EVENT:ContextConfig 解析 web.xml、掃描註解、合併配置
  3. 啟動子容器:所有 StandardWrapper(Servlet 實例)
  4. 會話管理器初始化:StandardManager
  5. 初始化參數與組件:initParam、啟動 Filter、Listener

生命週期模式總結

Tomcat 所有組件均遵循 Lifecycle 接口定義的統一生命週期:

  • init() / initInternal():資源分配、配置解析、MBean 註冊
  • start() / startInternal():啟動子組件、進入服務狀態、註冊監聽器
  • stop() / stopInternal():逆序關閉、資源釋放
  • destroy() / destroyInternal():徹底銷毀

基類 LifecycleBase 提供模板方法,子類實現 Internal 後綴方法定制具體行為。事件機制(FireLifecycleEvent)實現了組件間的解耦通信(如 ContextConfig 監聽 Context 事件)。

下一步預告

容器啟動完成後,StandardService 將啟動 Connector(Http11NioProtocol 等),建立網絡端口監聽。下一篇將深入分析連接器啟動、ProtocolHandler 初始化、Acceptor/Processor 線程模型等網絡層核心邏輯。

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