【Tomcat 原始碼系列】Tomcat 整體結構
阿新 • • 發佈:2020-12-16
# 一,前言
在開始看原始碼細節之前,首先要想好要看的問題。想好問題之後,我們該如何尋找要看的程式碼呢?
其實,這就好像去爬山的時候,突然想去上廁所,如果有一副地圖,那麼我們可以很快就找到廁所的位置。帶著問題看原始碼也是同樣的道理,如果我們知道原始碼每個部分的結構是做什麼的,那麼我們就可以很快定位程式碼。
這篇部落格主要介紹 Tomcat 的整體設計、原始碼結構。
## Tomcat 本質
Tomcat 本質上是什麼呢?我們上 Tomcat 的官網看看。下面這段來自官網,Tomcat 本質上就是實現了部分 Jakarta EE (Java EE 新的名字) 規範。我們日常使用中,一般都會說 Tomcat 是一個 Web 伺服器,它可以處理 Http 相關的請求。因此,Tomcat 是一個實現了部分 Jakarta EE 規範的 Web 伺服器。它有兩個主要的部分組成,一個是 Connector,一個是 Container。Connector 負責接收 Http 請求,並將請求轉發給 Container 去處理,Container 負責處理請求的內容,載入對應的 Servlet,將請求的結果返回給 Connector。
> The Apache Tomcat® software is an open source implementation of the Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket technologies.
# 二,專案原始碼結構
我們先從原始碼結構開始。Tomcat 伺服器相關的程式碼在 java 資料夾下面,後面我們在進入這個資料夾去分析。
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201213214551841-1493160230.png)
modules 資料夾下面,有四個部分。
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201213220114178-1488164293.png)
# 三,Tomcat 原始碼資料夾
Tomcat 原始碼位於 java 資料夾下面。這個 java 資料夾下面的每個東西是幹什麼事情的呢?下面簡要說說。
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215130506937-1323251881.png)
## 1. Jakarta
位於 `java/jakarta`,這個資料夾下面儲存的是新的 Java EE 規範,現在的 Java EE 也不這麼叫了,要改名叫 Jakarta EE。詳見[這裡](https://blogs.oracle.com/javamagazine/transition-from-java-ee-to-jakarta-ee)。
如果去看 tomcat 9,會發現這個資料夾是 javax,不是 jakarta。tomcat 10 的一個重大轉變就是從 javax 名稱空間轉向 jakarta。
每個規範是做什麼的呢?這裡參考官網[2]的[規範](https://jakarta.ee/specifications/)簡要說說。
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215131016476-1386903664.png)
### annotation
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215132429914-531714520.png)
**註解**。https://jakarta.ee/specifications/annotations/2.0/annotations-spec-2.0.html#goals
下面引用了網頁中的說法,annotation 這個模組的作用是定義了一些公用的註解,避免在不同的規範中定義相同的註解。
> It is hoped that this will help to avoid unnecessary redundancy or duplication between annotations defined in different Jakarta EE specifications
### ejb
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215132408094-535499327.png)
**Enterprise Beans**。https://jakarta.ee/specifications/enterprise-beans/4.0/jakarta-enterprise-beans-spec-core-4.0.htm
EJB 是開發和部署基於元件的企業級應用的架構。EJB 是一個架構。我是第一次聽說 EJB,所以只能是引用它的說法,看個定義了。
> The Enterprise Beans architecture is an architecture for the development and deployment of component-based business applications.
### el
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215132346590-143176187.png)
**Expression Language**。https://jakarta.ee/specifications/expression-language/4.0/jakarta-expression-language-spec-4.0.html
這個用在 jsp 中,用於求解表示式的值。
### mail
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215132332846-1369734672.png)
無需看規範,知道它是郵件相關的就行。
### persistence
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215132312021-114630912.png)
持久化相關。
### security
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215132249929-196320003.png)
安全相關。
### servlet
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215132230809-2047008055.png)
這個是重頭戲。從本質上說,tomcat 就是一個實現了 servlet 規範的一個容器。servlet 定義了服務端處理 Http 請求和響應的規範。
### transaction
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215132746106-780139494.png)
事務相關的介面。
### websocket
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215132909483-957905264.png)
定義了使用 websocket 協議的服務端和客戶端 API
### xml.ws
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215133101061-1078466662.png)
定義了基於 SOAP 協議的 xml 方式的 web 服務。
## 2. org.apache
`org/apache` 資料夾下面是關於上面規範的部分實現。Tomcat 本質上就是 Jakarta EE 某些規範實現的合集。
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215134033552-936875748.png)
### Catalina
tomcat 的核心程式碼,可以理解為一個 servlet 容器。
### coyote
tomcat 的核心程式碼,負責將網路請求轉化後和 Catalina 進行通訊。
### el
上面的 Jakarta EE 中 el 的實現。
### jasper
負責將 jsp 轉為 java 程式碼。
### juli
日誌相關的工具。
### naming
名稱空間相關。
### tomcat
各種輔助工具,包括 websocket 的實現。
# 四,Tomcat 模組設計
圖片來自於 [Medium](https://medium.com/@nikhilmanikonda/tomcat-who-i-am-and-what-i-do-e91ff72fb2ea)。
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215134302467-1010126314.png)
### 簡化
How Tomcat Works 一書中,把 Tomcat 簡化為 Connector 和 Container。
Connector 負責接收 Http 請求,並將請求轉發給 Container 去處理,Container 負責處理請求的內容,載入對應的 Servlet,將請求的結果返回給 Connector。
![](https://img2020.cnblogs.com/blog/1616773/202012/1616773-20201215224634431-1771367262.png)
# 五,總結
這篇文章從原始碼層面,從設計層面介紹了 Tomcat 的整體結構。後面我們帶著問題逐個分析原始碼,敬請期待。
有不懂的地方,也歡迎在評論區中交流討論。如有表述不準確的地方,希望能幫忙指出,謝謝~
# 參考連結
[1] https://blogs.oracle.com/javamagazine/transition-from-java-ee-to-jakarta-ee
[2] https://jakarta.ee/specifications/
[3] https://medium.com/@nikhilmanikonda/tomcat-who-i-am-and-what-i-do-e91f