Tomcat 啟動流程與類加載機制

Tomcat 啟動流程與類加載機制

在這里插入圖片描述

1. 引言

Tomcat 的啟動不僅僅是簡單的 java -jarcatalina.sh start
它背后包含 Bootstrap 啟動器、Catalina 控制器、Server/Service/Connector/Container 初始化 等關鍵步驟。

另一方面,Tomcat 為了支持 熱部署、不同應用間類隔離,設計了 破壞雙親委派機制的類加載模型,這是 Java Web 容器的核心機制。

本篇我們將從 啟動流程類加載機制 兩方面,全面剖析 Tomcat 內核。


2. Tomcat 啟動流程總覽

Tomcat 的啟動過程主要分為以下幾個階段:

  1. Bootstrap 初始化

    • 加載 catalina.properties
    • 初始化 Tomcat 的類加載器體系
  2. Catalina 初始化

    • 創建 Catalina 對象
    • 解析 server.xml 配置文件
  3. Server 與 Service 構建

    • 創建 StandardServer
    • 創建 StandardService,并綁定 Connector 與 Container
  4. 啟動 Server

    • 調用 server.start()
    • 啟動 Service → 啟動 Connector(協議監聽) & Container(加載 Web 應用)

👉 流程圖:

Bootstrap↓
Catalina↓
Server (StandardServer)↓
Service (StandardService)↓
Connector + Container↓
應用可對外提供服務

3. 啟動入口:Bootstrap

Tomcat 的入口類是 org.apache.catalina.startup.Bootstrap

public final class Bootstrap {public static void main(String[] args) {Bootstrap bootstrap = new Bootstrap();bootstrap.init();bootstrap.start();}
}

主要步驟:

  1. init()

    • 加載系統屬性、解析配置文件
    • 創建類加載器:CatalinaClassLoader
  2. start()

    • 反射調用 org.apache.catalina.startup.Catalinaload() 方法
    • Catalina 進一步加載 server.xml 并初始化 Server

4. Catalina 控制器

org.apache.catalina.startup.Catalina 是 Tomcat 的 核心控制器,負責解析配置文件并啟動 Server:

public void load() {Digester digester = createStartDigester(); // XML 解析器InputSource inputSource = getConfigFile("server.xml");digester.parse(inputSource); // 解析 server.xmlserver = (Server) digester.getRoot();
}
  • 使用 Digester(基于 SAX 的 XML 解析器)解析 server.xml
  • 創建 Server → Service → Connector/Container 的對象模型
  • 保存到內存,供后續啟動調用

5. Server 與 Service 初始化

Tomcat 的核心組件是通過 server.xml 配置加載的:

<Server port="8005" shutdown="SHUTDOWN"><Service name="Catalina"><Connector port="8080" protocol="HTTP/1.1"/><Engine name="Catalina" defaultHost="localhost"><Host name="localhost" appBase="webapps"/></Engine></Service>
</Server>
  • Server:代表整個 Tomcat 實例
  • Service:將 Connector 和 Container 組合
  • Connector:監聽端口、接收請求
  • Container:四層容器體系(Engine → Host → Context → Wrapper)

6. Server 啟動流程

當調用 server.start() 時:

  1. Server.start() → 啟動所有 Service
  2. Service.start() → 啟動 Connector 和 Container
  3. Connector.start() → 打開端口,開始監聽 HTTP/AJP 請求
  4. Container.start() → 加載 Web 應用,初始化 Servlet

源碼片段:

public class StandardServer extends LifecycleBase {@Overrideprotected void startInternal() throws LifecycleException {for (Service service : services) {service.start(); // 啟動 Service}}
}

7. Tomcat 的類加載機制

普通 Java 程序的類加載遵循 雙親委派機制

BootstrapClassLoader↓
ExtClassLoader↓
AppClassLoader↓
用戶自定義類加載器

但是 Tomcat 必須滿足:

  • 不同 Web 應用類相互隔離
  • 公共類(如 Servlet API)在所有應用共享
  • 支持熱部署、重新加載

因此 Tomcat 打破了雙親委派,設計了 多層類加載器模型


8. Tomcat 類加載器體系

Tomcat 的類加載器層次:

  1. Bootstrap ClassLoader(JVM 內置,加載 rt.jar 等)
  2. System ClassLoader(AppClassLoader)
  3. CommonClassLoader(加載 $CATALINA_HOME/lib
  4. CatalinaClassLoader(加載 Tomcat 自身核心類)
  5. SharedClassLoader(應用共享類)
  6. WebAppClassLoader(應用私有類,加載 WEB-INF/classesWEB-INF/lib

👉 層次關系圖:

BootstrapClassLoader↓
SystemClassLoader↓
CommonClassLoader├── CatalinaClassLoader (Tomcat 內部類)├── SharedClassLoader (共享庫)└── WebAppClassLoader (應用隔離)

9. 破壞雙親委派的實現

Tomcat 的 WebAppClassLoaderBase 重寫了 loadClass 方法:

@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {// 1. 先從緩存中找Class<?> clazz = findLoadedClass(name);if (clazz == null) {try {// 2. 先自己嘗試加載clazz = findClass(name);} catch (ClassNotFoundException e) {// 3. 加載不到再交給父加載器clazz = super.loadClass(name, resolve);}}return clazz;
}

區別:

  • 普通類加載器:先父后子(雙親委派)
  • Tomcat WebAppClassLoader:先子后父(保證 Web 應用的私有類優先加載)

10. 類加載機制的應用場景

  • Servlet API:在 CommonClassLoader 中加載,供所有應用共享
  • 第三方依賴(例如 Spring Jar 包):放在 WEB-INF/lib,由 WebAppClassLoader 加載,避免沖突
  • 熱部署:通過銷毀并重建 WebAppClassLoader 實現

11. 總結

在本篇中,我們詳細剖析了:

  1. 啟動流程

    • Bootstrap 初始化 → Catalina 控制器 → Server/Service → Connector/Container
  2. 類加載機制

    • 普通雙親委派 vs Tomcat 類加載模型
    • WebAppClassLoader 打破雙親委派,保證應用隔離
  3. 應用價值

    • 支持多應用隔離
    • 支持熱部署
    • 保證公共 API 的統一性

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/98105.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/98105.shtml
英文地址,請注明出處:http://en.pswp.cn/web/98105.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MTK Linux Charger驅動分析(十二)- mtk_pd_adapter.c

1. 代碼整體分析 mtk_pd_adapter.c(源文件) 主要內容: 該文件實現了MediaTek平臺的USB PD(Power Delivery)適配器驅動,基于Linux內核的電源管理和Type-C端口控制器(TCPC)框架。 它處理PD協議事件,包括PD連接狀態、Type-C狀態、水檢測(WD_STATUS)、Sink VBUS變化等。…

Spring Boot Logback 日志配置詳解:從基礎到分布式追蹤

日志是應用程序不可或缺的組成部分&#xff0c;它不僅能幫助我們調試問題&#xff0c;還能監控系統運行狀態。在 Spring Boot 生態中&#xff0c;Logback 憑借其高性能和靈活性成為首選的日志框架。本文將通過一個實際的 Logback 配置文件&#xff0c;詳細解析其各個組件的功能…

軟件體系結構——后端三層架構

三層架構——Controller、Service、Dao 不僅是對代碼進行的邏輯分層。其真正的本質&#xff0c;是將業務、技術和數據剝離。搞業務的專心做業務&#xff0c;搞技術的專心搞技術&#xff0c;做數據存儲的專心做數據存儲。三方通過接口進行對接&#xff0c;任一部分重構&#xff…

QML學習筆記(一)基本了解和工程配置

前言&#xff1a; 已經從事QT開發幾年了&#xff0c;但對于QML這個東西始終是沒有徹底掌握&#xff0c;一方面實際工作中沒有用到過&#xff0c;其次它的語法對我來說是全新的東西&#xff0c;不像QWidget那一套可以直接在C中去寫。這就是為什么網上都說qml更簡單&#xff0c;我…

SAP HANA Scale-out 04:緩存

結果緩存靜態結果緩存 Vs 動態結果緩存FeatureStatic Result CacheDynamic Result CacheTarget Scenario對復雜視圖&#xff08;通常是頂層視圖&#xff09;的查詢頻繁更新的大表&#xff08;例如ACDOCA&#xff09;上的聚合查詢Query result非實時數據實時數據ScopeTarget obj…

嘉興禾潤 HTR7216 (S) LED 驅動芯片:特性與應用

在如今智能設備飛速普及的時代&#xff0c;無論是智能家居的氛圍營造、IoT 設備的狀態提示&#xff0c;還是個人消費電子的視覺呈現&#xff0c;都離不開高性能 LED 驅動芯片的支撐。嘉興禾潤推出的 HTR7216 (S) LED 驅動芯片&#xff0c;憑借豐富的功能、精準的控制以及出色的…

Python實現劍龍優化算法 (Stegosaurus Optimization Algorithm, SOA)優化函數(付完整代碼)

Python實現劍龍優化算法 (Stegosaurus Optimization Algorithm, SOA)優化函數&#xff08;付完整代碼&#xff09;1.劍龍優化算法介紹劍龍優化算法&#xff08;Stegosaurus Optimization Algorithm&#xff0c;SOA&#xff09;是一種受劍龍獨特生理結構和行為模式啟發而設計的元…

分布式拜占庭容錯算法——權益證明(PoS)算法詳解

Java 實現權益證明&#xff08;PoS&#xff09;算法詳解 一、PoS 核心機制 #mermaid-svg-Sbj0HU6MjOl1yo5L {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Sbj0HU6MjOl1yo5L .error-icon{fill:#552222;}#mermaid-s…

【論文閱讀】谷歌:生成式數據優化,只需請求更好的數據

谷歌DeepMind團隊通過Generative Data Refinement&#xff08;GDR&#xff09;技術&#xff0c;成功將極端有毒的4chan討論數據轉化為安全且語義豐富的訓練素材&#xff0c;推動了LLM訓練數據凈化的新范式&#xff1a; ? GDR利用預訓練大模型對原始數據進行“重寫”&#xff0…

C++ 多線程實戰 10|C++20 的信號量、閂鎖與屏障

目錄 前言 學習目標 1. 信號量&#xff08;Semaphore&#xff09; 示例&#xff1a;限制并發下載任務 2. 閂鎖&#xff08;Latch&#xff09; 示例&#xff1a;賽跑 3. 屏障&#xff08;Barrier&#xff09; 示例&#xff1a;圖像處理流水線 4. 常見坑與對策 5. 實踐作…

【Java SE】01. 初識Java

1. 認識Java Java是一種優秀的程序設計語言&#xff0c;它具有令人賞心悅目的語法和易于理解的語義。Java還是一個有一系列計算機軟件和規范形成的技術體系&#xff0c;這個技術體系提供了完整的用于軟件開發和跨平臺部署的支持環境&#xff0c;并廣泛應用于嵌入式系統、移動終…

解鎖倉儲智能調度、運輸路徑優化、數據實時追蹤,全功能降本提效的智慧物流開源了

AI 視頻監控平臺&#xff1a;全鏈路協同驅動的智能監控解決方案AI 視頻監控平臺是一款融合高性能功能與輕量化操作的實時算法驅動型視頻監控系統&#xff0c;其核心愿景在于深度破除不同芯片廠商間的技術壁壘&#xff0c;省去冗余重復的適配環節&#xff0c;最終達成芯片、算法…

冒泡排序與選擇排序以及單鏈表與雙鏈表

1. 冒泡排序&#xff08;Bubble Sort&#xff09; 1. 原理 冒泡排序是一種 簡單的排序算法&#xff0c;通過 兩兩比較相鄰元素&#xff0c;把較大的元素逐漸 “冒泡” 到數組末尾。 思路&#xff1a; 從數組頭開始&#xff0c;比較相鄰兩個元素。 如果前一個比后一個大&…

Python實現計算點云投影面積

本次我們分享一種基于 Open3D 的快速、穩健方法&#xff0c;用于從激光點云中自動提取“地面”并計算其投影面積。算法先自適應估計地面高程&#xff0c;再將地面點投影至水平面&#xff0c;隨后用凸包或最小外接矩形求取面積。整個流程無需人工干預&#xff0c;單文件即可運行…

AXI4 協議

一、AXI4簡介AXI4&#xff08;Advanced eXtensible Interface 4&#xff09;是ARM公司推出的高性能片上總線協議&#xff0c;屬于AMBA&#xff08;Advanced Microcontroller Bus Architecture&#xff09;標準的一部分。它專為高帶寬、低延遲的片上通信設計&#xff0c;廣泛應用…

《餓殍:明末千里行》Switch版試玩發布 3月13日發售

使用jQuery的常用方法與返回值分析 jQuery是一個輕量級的JavaScript庫&#xff0c;旨在簡化HTML文檔遍歷和操作、事件處理以及動畫效果的創建。本文將介紹一些常用的jQuery方法及其返回值&#xff0c;幫助開發者更好地理解和運用這一強大的庫。 1. 選擇器方法 jQuery提供了多種…

[特殊字符] 認識用戶手冊用戶手冊(也稱用戶指南、產品手冊)是通過對產品功能的清

一份優秀的用戶手冊能有效降低用戶的使用門檻&#xff0c;提升用戶體驗和工作效率。下面我將為你梳理編寫用戶手冊的核心要點、步驟和技巧。&#x1f4d6; 認識用戶手冊用戶手冊&#xff08;也稱用戶指南、產品手冊&#xff09;是??通過對產品功能的清晰解釋&#xff0c;為特…

蘋果軟件代碼混淆,iOS混淆、iOS加固、ipa安全與合規取證注意事項(實戰指南)

在移動軟件交付與合規審計中&#xff0c;蘋果軟件代碼混淆已成為保護知識產權與用戶數據的常規手段。但混淆帶來的不僅是逆向難度的提升&#xff0c;也會觸發崩潰取證、符號化&#xff08;symbolication&#xff09;、審計合規與法律證據保存等問題。本文從工程與合規雙視角出發…

Redis框架詳解

目錄 1. redis是什么 主要特點 2. redis中存儲的數據類型 2.1 String類型 2.2 List類型 2.3 Hash類型 2.4 Set類型 2.5 Zset類型 2.6 其它類型 3.redis高可用框架 1. redis是什么 Redis 是一個開源的、基于內存的數據結構存儲系統&#xff0c;是 Remote Dictionary…