tomcat架构分析(容器类)【转】
原文地址:https://www.iteye.com/blog/gearever-1533678
Tomcat提供了engine,host,context及wrapper四種容器。在總體結(jié)構(gòu)中已經(jīng)闡述了他們之間的包含關(guān)系。這四種容器繼承了一個容器基類,因此可以定制化。當然,tomcat也提供了標準實現(xiàn)。
- Engine:org.apache.catalina.core.StandardEngine
- Host: org.apache.catalina.core.StandardHost
- Context:org.apache.catalina.core.StandardContext
- Wrapper:org.apache.catalina.core.StandardWrapper
所謂容器,就是說它承載了若干邏輯單元及運行時數(shù)據(jù)。好比,整個酒店是一個容器,它包含了各個樓層等設施;每個樓層也是容器,它包含了各個房間;每個房間也是容器,它包含了各種家電等等。?
首先來看一下容器類的類結(jié)構(gòu)。?
基類ContainerBase
ContainerBase是個abstract基類。其類路徑為:
這里只列出一些比較核心功能的組件及方法。需要注意的是,類中的方法及屬性很多,限于篇幅不全部列出來了。?
Enigne
Engine是最頂層的容器,它是host容器的組合。其標準實現(xiàn)類為:
看一下StandardEngine的主要邏輯單元概念圖。
從圖中可以看出,engine有四大組件:
- Cluster: 實現(xiàn)tomcat集群,例如session共享等功能,通過配置server.xml可以實現(xiàn),對其包含的所有host里的應用有效,該模塊是可選的。其實現(xiàn)方式是基于pipeline+valve模式的,有時間會專門整理一個pipeline+valve模式應用系列;
- Realm:實現(xiàn)用戶權(quán)限管理模塊,例如用戶登錄,訪問控制等,通過通過配置server.xml可以實現(xiàn),對其包含的所有host里的應用有效,該模塊是可選的;
- Pipeline:這里簡單介紹下,之后會有專門文檔說明。每個容器對象都有一個pipeline,它不是通過server.xml配置產(chǎn)生的,是必須有的。它就是容器對象實現(xiàn)邏輯操作的骨架,在pipeline上配置不同的valve,當需要調(diào)用此容器實現(xiàn)邏輯時,就會按照順序?qū)⒋藀ipeline上的所有valve調(diào)用一遍,這里可以參考責任鏈模式;
- Valve:實現(xiàn)具體業(yè)務邏輯單元。可以定制化valve(實現(xiàn)特定接口),然后配置在server.xml里。對其包含的所有host里的應用有效。定制化的valve是可選的,但是每個容器有一個缺省的valve,例如engine的StandardEngineValve,是在StandardEngine里自帶的,它主要實現(xiàn)了對其子host對象的StandardHostValve的調(diào)用,以此類推。
配置的例子有:
需要注意的是,運行環(huán)境中,pipeline上的valve數(shù)組按照配置的順序加載,但是無論有無配置定制化的valve或有多少定制化的valve,每個容器缺省的valve,例如engine的StandardEngineValve,都會在數(shù)組中最后一個。?
Host
Host是engine的子容器,它是context容器的集合。其標準實現(xiàn)類為:
StandardHost的核心模塊與StandardEngine差不多。只是作用域不一樣,它的模塊只對其包含的子context有效。除此,還有一些特殊的邏輯,例如context的部署。Context的部署還是比較多的,主要分為:
- War部署
- 文件夾部署
- 配置部署等
有時間單獨再說吧。照例貼個核心模塊概念圖。?
Context
Context是host的子容器,它是wrapper容器的集合。其標準實現(xiàn)類為:
應該說StandardContext是tomcat中最大的一個類。它封裝的是每個web app。
看一下StandardContext的主要邏輯單元概念圖。?
Pipeline,valve,realm與上面容器一樣,只是作用域不一樣,不多說了。
- Manager: 它主要是應用的session管理模塊。其主要功能是session的創(chuàng)建,session的維護,session的持久化(persistence),以及跨context的session的管理等。Manager模塊可以定制化,tomcat也給出了一個標準實現(xiàn);
manager模塊是必須要有的,可以在server.xml中配置,如果沒有配置的話,會在程序里生成一個manager對象。
- Resources: 它是每個web app對應的部署結(jié)構(gòu)的封裝,比如,有的app是tomcat的webapps目錄下的某個子目錄或是在context節(jié)點配置的其他目錄,或者是war文件部署的結(jié)構(gòu)等。它對于每個web app是必須的。
- Loader:它是對每個web app的自有的classloader的封裝。具體內(nèi)容涉及到tomcat的classloader體系,會在一篇文檔中單獨說明。Tomcat正是有一套完整的classloader體系,才能保證每個web app或是獨立運營,或是共享某些對象等等。它對于每個web app是必須的。
- Mapper:它封裝了請求資源URI與每個相對應的處理wrapper容器的映射關(guān)系。
以某個web app的自有的web.xml配置為例;
對于mapper對象,可以抽象的理解成一個map結(jié)構(gòu),其key是某個訪問資源,例如/*.do,那么其value就是封裝了處理這個資源TestServlet的某個wrapper對象。當訪問/*.do資源時,TestServlet就會在mapper對象中定位到。這里需要特別說明的是,通過這個mapper對象定位特定的wrapper對象的方式,只有一種情況,那就是在servlet或jsp中通過forward方式訪問資源時用到。例如,
關(guān)于mapper機制會在一篇文檔中專門說明,這里簡單介紹一下,方便理解。如圖所示。
Mapper對象在tomcat中存在于兩個地方(注意,不是說只有兩個mapper對象存在),其一,是每個context容器對象中,它只記錄了此context內(nèi)部的訪問資源與相對應的wrapper子容器的映射;其二,是connector模塊中,這是tomcat全局的變量,它記錄了一個完整的映射對應關(guān)系,即根據(jù)訪問的完整URL如何定位到哪個host下的哪個context的哪個wrapper容器。
這樣,通過上面說的forward方式訪問資源會用到第一種mapper,除此之外,其他的任何方式,都是通過第二種方式的mapper定位到wrapper來處理的。也就是說,forward是服務器內(nèi)部的重定向,不需要經(jīng)過網(wǎng)絡接口,因此只需要通過內(nèi)存中的處理就能完成。這也就是常說的forward與sendRedirect方式重定向區(qū)別的根本所在。
看一下request.getRequestDispatcher(url) 方法的源碼。
紅色部分標記了從context的mapper對象中定位wrapper子容器,然后封裝在一個dispatcher對象內(nèi)并返回。通過上面的闡述,也說明了為什么forward方法不能跨context訪問資源了。
Wrapper
Wrapper是context的子容器,它封裝的處理資源的每個具體的servlet。其標準實現(xiàn)類為:
應該說StandardWrapper是tomcat中比較重要的一個類。初認識它時,比較容易混淆。
先看一下StandardWrapper的主要邏輯單元概念圖。?
Pipeline,valve與上面容器一樣,只是作用域不一樣,不多說了。
主要說說servlet對象與servlet stack對象。這兩個對象在wrapper容器中只存在其中之一,也就是說只有其中一個不為空。當以servlet對象存在時,說明此servlet是支持多線程并發(fā)訪問的,也就是說不存在線程同步的過程,此wrapper容器中只包含一個servlet對象(這是我們常用的模式);當以servlet stack對象存在時,說明servlet是不支持多線程并發(fā)訪問的,每個servlet對象任一時刻只有一個線程可以調(diào)用,這樣servlet stack實現(xiàn)的就是個簡易的線程池,此wrapper容器中只包含一組servlet對象,它的基本原型是worker thread模式實現(xiàn)的。?
那么,怎么來決定是以servlet對象方式存儲還是servlet stack方式存儲呢?其實,只要在開發(fā)servlet類時,實現(xiàn)一個SingleThreadModel接口即可。
如果需要線程同步的servlet類,例如:
但是值得注意的是,這種同步機制只是從servlet規(guī)范的角度來說提供的一種功能,在實際應用中并不能完全解決線程安全問題,例如如果servlet中有static數(shù)據(jù)訪問等,因此如果對線程安全又比較嚴格要求的,最好還是用一些其他的自定義的解決方案。
Wrapper的基本功能已經(jīng)說了。那么再說一個wrapper比較重要的概念。嚴格的說,并不是每一個訪問資源對應一個wrapper對象。而是每一種訪問資源對應一個wrapper對象。其大致可分為三種:
- 處理靜態(tài)資源的一個wrapper:例如html,jpg等靜態(tài)資源的wrapper,它包含了一個tomcat的實現(xiàn)處理靜態(tài)資源的缺省servlet:
?
Java代碼???
- 處理jsp的一個wrapper:例如訪問的所有jsp文件,它包含了一個tomcat的實現(xiàn)處理jsp的缺省servlet:
?
Java代碼??
它主要實現(xiàn)了對jsp的編譯等操作
- 處理servlet的若干wrapper:它包含了自定義的servlet對象,就是在web.xml中配置的servlet。
需要注意的是,前兩種wrapper分別是一個,主要是其對應的是DefaultServlet及JspServlet。這兩個servlet是在tomcat的全局conf目錄下的web.xml中配置的,當app啟動時,加載到內(nèi)存中。
至此,闡述了tomcat的四大容器結(jié)構(gòu)。 有時間接著探討tomcat如何將這四大容器串起來運作的。
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/articles/11452693.html
總結(jié)
以上是生活随笔為你收集整理的tomcat架构分析(容器类)【转】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

- 上一篇: tomcat架构分析(connector
- 下一篇: tomcat架构分析 (connecto