3.TOMCAT Container 分析

Container是容器的父接口,該容器的設(shè)計(jì)用的是典型的責(zé)任鏈的設(shè)計(jì)模式,它由四個(gè)自容器組件構(gòu)成,分別是Engine、Host、Context、Wrapper。這四個(gè)組件是負(fù)責(zé)關(guān)系,存在包含關(guān)系。通常一個(gè)Servlet class對(duì)應(yīng)一個(gè)Wrapper,如果有多個(gè)Servlet定義多個(gè)Wrapper,如果有多個(gè)Wrapper就要定義一個(gè)更高的Container,如Context。

Context 還可以定義在父容器 Host 中,Host 不是必須的,但是要運(yùn)行 war 程序,就必須要 Host,因?yàn)?war 中必有 web.xml 文件,這個(gè)文件的解析就需要 Host 了,如果要有多個(gè) Host 就要定義一個(gè) top 容器 Engine 了。而 Engine 沒有父容器了,一個(gè) Engine 代表一個(gè)完整的 Servlet 引擎。


image.png

Engine 容器
Engine 容器比較簡(jiǎn)單,它只定義了一些基本的關(guān)聯(lián)關(guān)系

Host 容器
Host 是 Engine 的字容器,一個(gè) Host 在 Engine 中代表一個(gè)虛擬主機(jī),這個(gè)虛擬主機(jī)的作用就是運(yùn)行多個(gè)應(yīng)用,它負(fù)責(zé)安裝和展開這些應(yīng)用,并且標(biāo)識(shí)這個(gè)應(yīng)用以便能夠區(qū)分它們。它的子容器通常是 Context,它除了關(guān)聯(lián)子容器外,還有就是保存一個(gè)主機(jī)應(yīng)該有的信息。

Context 容器
Context 代表 Servlet 的 Context,它具備了 Servlet 運(yùn)行的基本環(huán)境,理論上只要有 Context 就能運(yùn)行 Servlet 了。簡(jiǎn)單的 Tomcat 可以沒有 Engine 和 Host。Context 最重要的功能就是管理它里面的 Servlet 實(shí)例,Servlet 實(shí)例在 Context 中是以 Wrapper 出現(xiàn)的,還有一點(diǎn)就是 Context 如何才能找到正確的 Servlet 來執(zhí)行它呢? Tomcat5 以前是通過一個(gè) Mapper 類來管理的,Tomcat5 以后這個(gè)功能被移到了 request 中,在前面的時(shí)序圖中就可以發(fā)現(xiàn)獲取子容器都是通過 request 來分配的。

Wrapper 容器
Wrapper 代表一個(gè) Servlet,它負(fù)責(zé)管理一個(gè) Servlet,包括的 Servlet 的裝載、初始化、執(zhí)行以及資源回收。Wrapper 是最底層的容器,它沒有子容器了,所以調(diào)用它的 addChild 將會(huì)報(bào)錯(cuò)。
Wrapper 的實(shí)現(xiàn)類是 StandardWrapper,StandardWrapper 還實(shí)現(xiàn)了擁有一個(gè) Servlet 初始化信息的 ServletConfig,由此看出 StandardWrapper 將直接和 Servlet 的各種信息打交道。

Container如何處理請(qǐng)求的

Container處理請(qǐng)求是使用Pipeline-Valve管道來處理的?。╒alve是閥門之意)

Pipeline-Valve是責(zé)任鏈模式,責(zé)任鏈模式是指在一個(gè)請(qǐng)求處理的過程中有很多處理者依次對(duì)請(qǐng)求進(jìn)行處理,每個(gè)處理者負(fù)責(zé)做自己相應(yīng)的處理,處理完之后將處理后的請(qǐng)求返回,再讓下一個(gè)處理著繼續(xù)處理。

image.png
image.png

我們知道Container包含四個(gè)子容器,而這四個(gè)子容器對(duì)應(yīng)的BaseValve分別在:StandardEngineValve、StandardHostValve、StandardContextValve、StandardWrapperValve。

Pipeline的處理流程圖如下:

image.png

(1)Connector在接收到請(qǐng)求后會(huì)首先調(diào)用最頂層容器的Pipeline來處理,這里的最頂層容器的Pipeline就是EnginePipeline(Engine的管道);

(2)在Engine的管道中依次會(huì)執(zhí)行EngineValve1、EngineValve2等等,最后會(huì)執(zhí)行StandardEngineValve,在StandardEngineValve中會(huì)調(diào)用Host管道,然后再依次執(zhí)行Host的HostValve1、HostValve2等,最后在執(zhí)行StandardHostValve,然后再依次調(diào)用Context的管道和Wrapper的管道,最后執(zhí)行到StandardWrapperValve。

(3)當(dāng)執(zhí)行到StandardWrapperValve的時(shí)候,會(huì)在StandardWrapperValve中創(chuàng)建FilterChain,并調(diào)用其doFilter方法來處理請(qǐng)求,這個(gè)FilterChain包含著我們配置的與請(qǐng)求相匹配的Filter和Servlet,其doFilter方法會(huì)依次調(diào)用所有的Filter的doFilter方法和Servlet的service方法,這樣請(qǐng)求就得到了處理!

(4)當(dāng)所有的Pipeline-Valve都執(zhí)行完之后,并且處理完了具體的請(qǐng)求,這個(gè)時(shí)候就可以將返回的結(jié)果交給Connector了,Connector在通過Socket的方式將結(jié)果返回給客戶端。

image.png

1、用戶點(diǎn)擊網(wǎng)頁內(nèi)容,請(qǐng)求被發(fā)送到本機(jī)端口8080,被在那里監(jiān)聽的Coyote HTTP/1.1 Connector獲得。
2、Connector把該請(qǐng)求交給它所在的Service的Engine來處理,并等待Engine的回應(yīng)。
3、Engine獲得請(qǐng)求localhost/test/index.jsp,匹配所有的虛擬主機(jī)Host。
4、Engine匹配到名為localhost的Host(即使匹配不到也把請(qǐng)求交給該Host處理,因?yàn)樵揌ost被定義為該Engine的默認(rèn)主機(jī)),名為localhost的Host獲得請(qǐng)求/test/index.jsp,匹配它所擁有的所有的Context。Host匹配到路徑為/test的Context(如果匹配不到就把該請(qǐng)求交給路徑名為“ ”的Context去處理)。
5、path=“/test”的Context獲得請(qǐng)求/index.jsp,在它的mapping table中尋找出對(duì)應(yīng)的Servlet。Context匹配到URL PATTERN為*.jsp的Servlet,對(duì)應(yīng)于JspServlet類。
6、構(gòu)造HttpServletRequest對(duì)象和HttpServletResponse對(duì)象,作為參數(shù)調(diào)用JspServlet的doGet()或doPost().執(zhí)行業(yè)務(wù)邏輯、數(shù)據(jù)存儲(chǔ)等程序。
7、Context把執(zhí)行完之后的HttpServletResponse對(duì)象返回給Host。
8、Host把HttpServletResponse對(duì)象返回給Engine。
9、Engine把HttpServletResponse對(duì)象返回Connector。
10、Connector把HttpServletResponse對(duì)象返回給客戶Browser。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容