前言
這篇文章是我們深入理解 Tomcat 的第十篇文章,也是總結(jié)文章, 學(xué)習(xí)就是這樣,先是理論,再是實(shí)踐,最后是總結(jié), 樓主習(xí)慣了在每次學(xué)習(xí)之后總結(jié), 讓從腦海中過的知識(shí)能夠再扎實(shí)一點(diǎn).
我們的第一篇文章 << 深入理解 Tomcat(一)源碼環(huán)境搭建和 How Tomcat works 源碼>>中介紹了樓主下載的源碼和 git 地址, 方便大家去 clone 源碼,不然怎么來依據(jù)理論去剖析源碼實(shí)現(xiàn)呢? 樓主認(rèn)為, 任何一門技術(shù)都要借助文檔和源碼一起去理解(可能是樓主比較菜). 而樓主也放了2個(gè)源碼,一個(gè)是使用 maven 改過的 tomcat 7 源碼,一個(gè)是名著 <<How Tomcat Works>> 的實(shí)例源碼, 方便我們更深入的理解 tomcat.
源碼環(huán)境搭建好了,樓主從網(wǎng)上,從早上... 額,不, 從各個(gè)地方看文章, 想了解 tomcat 的結(jié)構(gòu)設(shè)計(jì)和文檔, 當(dāng)然也搭配樓主從圖書館借來的 <<How Tomcat Works>> 書, 最終寫了一篇 <<深入理解 Tomcat (二) 從宏觀上理解 Tomcat 組件及架構(gòu)>>, 我們講了我們準(zhǔn)備如何學(xué)習(xí), 以及什么是 Tomcat , 什么是 Servlet, tomcat 源碼目錄的解釋, tomcat 整體框架的層次結(jié)構(gòu)和架構(gòu)圖, 分析每個(gè)組件, 包括 Connector, Container, Component, 也從接口和類的角度(UML 類圖)看架構(gòu). 這讓我們對(duì) tomcat 整體也有了一個(gè)大致的了解, 為我們接下來的分析源碼做了鋪墊.
我們?cè)诖笾铝私饬?tomcat 的整體架構(gòu)和設(shè)計(jì)后, 我們想了解一個(gè)最簡(jiǎn)單的 web 服務(wù)器是如何實(shí)現(xiàn)的, 我們寫了一篇<< 深入理解 Tomcat(三)Tomcat 底層實(shí)現(xiàn)原理>>, 參照<<How Tomcat Works>>源碼實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的阻塞式的 Web 服務(wù)器, 雖然現(xiàn)在最新的 Tomcat 9 已經(jīng)將阻塞 socket 去除了,全部使用 NIO 和 JNI 以提高速度, 但他仍是我們學(xué)習(xí)的一個(gè)很好的例子.
在了解原理之后, 我們開始循序漸進(jìn), 我們的第一個(gè)研究的就是著名的 Tomcat 的類加載機(jī)制, 于是我們寫了一篇 << 深入理解 Tomcat(四)Tomcat 類加載器之為何違背雙親委派模型>>, 先從 java 的類加載器開始分析, 分析雙親委任模型的原理, 以及類加載機(jī)制的發(fā)展及變化, 最后講 Tomcat 的類加載機(jī)制的設(shè)計(jì), 講 Tomcat 為何破壞雙親委派模型. 也講了 Tomcat 中每個(gè)類加載器的功能. 從理論上了解了 Tomcat 類加載器的設(shè)計(jì). 為我們從源碼層面理解做了鋪墊.
在了解了 Tomcat 的類加載器理論后, 我們第一次開始 debug tomcat 的源碼, 寫了一篇<<深入理解 Tomcat(五)源碼剖析Tomcat 啟動(dòng)過程----類加載過程>>, 從 BootStrap 開始, 我們一步步分析 Tomcat 是如何加載類,加載 jar 包, 是如何將公用的 jar 包使用 common 類加載器, 而私有的 jar 包及 web 應(yīng)用使用
WebAppClassLoader 的. 并且知道了 WebAppClassLoader的加載時(shí)間和另外幾個(gè)的時(shí)間不一致. 從源碼層面知道了 Tomcat 的類加載設(shè)計(jì)和機(jī)制.
我們繼續(xù)深入 tomcat, 開始按照我們?cè)诘诙恼轮械挠?jì)劃去閱讀源碼, 我們寫了 << 深入理解 Tomcat(六)源碼剖析Tomcat 啟動(dòng)過程----生命周期和容器組件>>, 深入源碼去了解 tomcat 是如何設(shè)計(jì)容器,容器是如何初始化的, 又是如何交給 JMX 去管理對(duì)象的. tomcat 的眾多容器又是如何通過觀察者模式來管理他們的生命周期的.
在了解了 tomcat 的生命周期組件和容器初始化過程后, 我們決定從整體上看看 tomcat 是如何啟動(dòng)的又是如何關(guān)閉的, 我們寫了 <<深入理解 Tomcat(七)源碼剖析 Tomcat 完整啟動(dòng)過程>>并且也見到 tomcat 傳說中的鉤子. tomcat 的關(guān)閉很有趣, 靠著啟動(dòng)一個(gè) socket 去發(fā)送SHUTDOWN命令.
之后我們決定去深入另一個(gè)很重要的組件----連接器, 在 <<深入理解 Tomcat(八)源碼剖析之連接器>>中, 我們深入源碼, 理解了連接器 Connector 的構(gòu)造過程, 連接器是如何初始化的, 又是如何啟動(dòng), 啟動(dòng)之后如何監(jiān)聽 Http 請(qǐng)求端口的. 如何處理瀏覽器發(fā)送過來的 socket 請(qǐng)求的.這些實(shí)在是太有意思了.
最后我們以一個(gè)最常見的請(qǐng)求為基礎(chǔ), 寫了 <<深入理解 Tomcat(九)源碼剖析之請(qǐng)求過程>>, 理解了一個(gè) HTTP 請(qǐng)求是如何從 socket 到達(dá)我們編寫的 Servlet 的, 并且了解了tomcat 是如何設(shè)計(jì)各個(gè)容器直接的通信----使用管道和閥門. 也知道了 tomcat 是如何解析消息頭, 如何設(shè)計(jì)過濾器. 讓我們對(duì) tomcat 的認(rèn)識(shí)可以說更加的清晰.我們無意中也發(fā)現(xiàn)了 tomcat 7 中關(guān)于單例模式的一個(gè)潛在 bug(最新的 tomcat 已經(jīng)修復(fù)).
最后, 就到了我們這篇總結(jié)的文章, 總的來說, 我們完成了我們最初定制的任務(wù), 剖析了最重要的幾個(gè)組件, 包括類加載器, 容器, 生命周期管理, 連接器, 管道, 閥門, 從啟動(dòng)過程和請(qǐng)求過程這兩條路線去分析源碼, 讓我們不會(huì)在浩瀚的源碼世界迷路. 雖然還要一些源碼沒有閱讀, 但我們相信, 我們已經(jīng)體會(huì)到了 tomcat 最重要的東西, 我們也不可能將所有的源碼全都閱讀一遍, 樓主是萬萬做不到的.
想想樓主最初閱讀源碼的目的, 就是好奇 tomcat 到底是如何實(shí)現(xiàn)的. 現(xiàn)在, 樓主認(rèn)為樓主的疑問已經(jīng)被解答, 接下來, 樓主就要研究另一個(gè) Java 世界中有名的框架了, 樓主不要做個(gè)只知道 know how 不知道 know why 的人.
加油!!! good luck !!!!