程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Tomcat研究之組件結構

Tomcat研究之組件結構

編輯:關於JAVA

大家好,上篇介紹了《Tomcat研究之ClassLoader》,這篇我們介紹組件結構

在沒有任何實質性資料的前提下研究Tomcat的內核將是非常困難的事情,但無論如何還有opensource,我們至少可以跟蹤Tomcat成百上千的類,為了我們能徹底解開Tomcat的面紗,我們還是要繼續努力.

通過UML類圖不難看出,Core包裡面最重要的一個類是ContainerBase,而這個抽象類實現了Container, Lifecycle, Pipeline, MBeanRegistration, Serializable接口, Serializable接口大家都已很熟悉,我們重在研究前幾個接口,因為我們猜想整個Tomcat的部分構架可能是建立在這幾個基礎接口上.

在進入分析之前我們先回憶一下config.xml(server.XML)文件,從這個文件及apache的文檔我們大體可以了解到Tomcat宏觀上是有下面幾個部分組成:

- Server server元素是JVM的入口點,整個配置文件只有一個,因為server不是容器(container),因此不能嵌套子組件.server在某一指定的端口監聽shutdown命令.server可以包含一個或多個service實。

- Service service有共享同一個Container的一個或多個Connectors組成,一般Service就是一個Engine,但沒有明確規范要求如此.因為Service不是一個Container,因此不能在裡面嵌套子組件(比如Loggers/Valves)。

- Connector connector就是一個Tomcat與客戶端的連接,Tomcat有兩種典型的Connector:http,JK2.http connector監聽來自Browser的連接(通常在我們熟悉的8080端口),JK2.來自其他WebServer的請求(默認在8009端口監聽)。Connector會把獲得的請求交給Engine處理。

- Engine Engine下可以配置多個虛擬主機Virtual Host,每個虛擬主機都有一個域名當Engine獲得一個請求時,它把該請求匹配到某個Host上,然後把該請求交給該Host來處理Engine有一個默認虛擬主機,當請求無法匹配到任何一個Host上的時候,將交給該默認Host來處理

- Host host代表一個虛擬主機,默認是localhost,host下可以部署多個web application,在我們實際應用中一般要考慮問題的對象就是host

1. org.apache.catalina.Lifecycle

通用的組件聲明周期接口,一般Tomcat的組件都要實現這個接口(但不是必須的),這個接口是為所有組件提供相同的start和stop。主要方法有:

//增加一個監聽器

public void addLifecycleListener(LifecycleListener listener);

/**

*這個方法應該在任何public方法被調用前被調用

*該方法發送一個START_EVENT事件到所有注冊到

*該組件的監聽器

*/

public void start() throws LifecycleException;

/**

*這個方法應該在所有public方法被調用之後被調用

*該方法發送一個STOP_EVENT事件到所有注冊到

*該組件的監聽器

*/

public void stop() throws LifecycleException;

2. org.apache.catalina. LifecycleListener

該接口用於監聽一些重要事件(包括實現了Lifecycle接口組件產生的start,stop事件)

主要方法是:

//處理監聽到的事件

public void lifecycleEvent(LifecycleEvent event);

3. org.apache.catalina.Container

容器是用於從客戶端取得請求(request)並且處理請求並回復給客戶端(response)的對象。容器可以支持(可選)pipeline,以便能在運行時按配置的順序處理請求。

在Tomcat裡面,容器在概念上存在以下及層:

Engine 請求處理入口點,可以包含多個Host和Context

Host 代表一個虛擬主機

Context 代表單個ServletContext,可以包含多個Wrappers

Wrapper 代表單個Servlet,如果Servlet實現了SingleThreadModel,可以代表單個Servlet的多個實例。

容器為了實現自己的功能經常要綁定一些其他組件,這些組件的功能可能被共享,也可以被單獨定制,下面是被使用的組件:

Loader ClassLoader,裝載Java Classes

Logger 實現了ServletContext的log方法,用於記錄日志

Manager 管理與容器綁定的session池

Realm 用戶安全管理

Resources JNDI資源訪問

主要的方法:

//增加容器監聽器

public void addContainerListener(ContainerListener listener);

//增加property監聽器

public void addPropertyChangeListener(PropertyChangeListener listener);

/**

*處理Request,並產生相應地Response

*param request 處理的請求

*param response 產生的response

*/

public void invoke(Request request, Response response) throws IOException, ServletException;

4. org.apache.catalina. ContainerListener

容器事件監聽器,注意的是start,stop是正常的生命周期事件(LiftcycleEvent)不是容器事件。主要方法:

//處理容器事件

public void containerEvent(ContainerEvent event);

5. org.apache.catalina. Pipeline

Pipleline是Valve的集合,當invoke方法被調用時,它會按指定的順序調用Valve,它總是要求有一個Valve必須處理傳遞的request(一般是最後一個)並產生response,否則就把request傳遞到下一個Valve。

一般一個容器僅綁定一個Pipleline實例,一般說來容器會把處理request的功能封裝到一個容器綁定的Valve裡(這個Valve應該在Pipleline最後被執行)。為了完成這個功能,Pipleline提供了setBasic()方法以保證Valve被最後執行,而其他Valve按順序被調用。

6. org.apache.catalina.Valve

Valve是被綁定在一個Container上的請求處理組件,一組Valve被按順序綁定在一個Pipleline上。Valve最重要的一個方法是:

/**

*一個Valve可能按照一定的順序執行下面的動作

*1.檢查並且(或者)修改指定的Request和Response屬性

*2.檢查Request屬性,生成相應的Response並返回控制權到調用者

*3.檢查Request和Reponse屬性,包裝這些對象並增強它們的功能,然後把它們傳

到下一個組件

*4.如果相應的Response沒有被產生(並且控制權也沒有被返回)調用Pipleline

上的下一個Valve(如果有)通過方法context.invokeNext()

*5.檢查(但不修改)Response屬性(調用後面的Valve或Container產生的)

*Valve一定不能作下面的事情

*1.改變Request的一些屬性(Change request propertIEs that have

already been used to direct the flow of processing control

for this request)

*2.創建一個已經被創建並且已經被傳遞的Response

*3.在調用invokeNext()方法並返回後修改包含Response的HTTP Header信息

*4.在invokeNext()調用返回後在綁定Response上的輸出流上作任何調用

*@param request 將被處理的Request

*@param response 將被創建的Response

*@param context 被用來調用下一個Valve的Valve Context

public void invoke(Request request, Response response,

ValveContext context)

throws IOException, ServletException;

7. org.apache.catalina.ValveContext

一個ValveContext是這樣一種機制:一個Valve可以觸發下一個Valve的調用,而不必知道機制的內在實現。

8. org.apache.catalina.Engine

Engine是一個容器,是Cataline的Servlet的入口點。

當發布一個連接到Web Server的Cataline時可能不使用Engine,因為Connectior將使用Web Server的資源決定使用哪個Context處理Request。

附屬於Engine的子容器根據Engine實現的不同可能是Host或Context(單個Servlet Context)。

如果使用了Engine,在Cataline的層次中它就是頂層容器,因此setParent()應改拋出IllegalArgumentException異常。從Engine下面幾個方法我們可以看出其的結構:

/**

* 設定Engine附屬的Service

* @param service The service that owns this Engine

*/

public void setService(Service service);

/**

* Set the default hostname for this Engine.

*

* @param defaultHost The new default host

*/

public void setDefaultHost(String defaultHost);

/**

* Set the DefaultContext

* for new web applications.

*

* @param defaultContext The new DefaultContext

*/

public void addDefaultContext(DefaultContext defaultContext);

9. org.apache.catalina. Host

Host是一個容器,它代表一個虛擬主機。

當發布一個連接到Web Server的Cataline時可能不使用Host,因為Connectior將使用Web Server的資源決定使用哪個Context處理Request。

Host所附屬的父容器通常是Engine,附屬於Host的子容器通常是Context(單個Servlet Context)。

Host接口裡面的方法多數都是關於修改Host屬性及設定默認的Context。這裡我們不再一一列舉。

10. org.apache.catalin. Context

Context是一個容器,它代表一個ServletContext,一個Cataline Engline中的單個的Web Application。Context所附屬的父容器是Host,附屬於Context的子容器是Wrapper(代表單個Servlet)。Context接口裡面多數是關於Web Application的設置的方法,我們可以參考Web.xml文件研究裡面的方法,裡面多數方法都是如何讀取Web.XML文件裡的資源。

11. org.apache.catalina.Wrapper

Wrapper是一個容器,它代表單個Servlet。Wrapper管理Servlet的生命周期,包括調用init()和destory()方法。

Wrapper所附屬的父容器是Context,沒有附屬於Wrapper的子容器,方法addChild()應該拋出IllegalArgumentException異常。

Wrapper接口裡面的方法都是關於讀取Servlet的屬性,可以參考Web.XML文件裡面關於標簽的定義。

12. org.apache.catalina.Server

Server是整個Catalina容器的入口點,可以包含多個Service和頂層資源元素。一般說來實現Server接口的類也應該同時實現Lifecycle接口,當start()和stop()方法被調用的時候調用Service相應的方法。

Server負責在指定的端口監聽連接,當有連接被接受的時候,Server會分析請求的第一行信息,如果是SHUTDOWN則stop服務。可以參考Server.XML文件關於Server的定義。

13. org.apache.catalina. Service

Service是一個或多個共享同以Container的Connectiors的集合。

JVM可以包含一個或多個Service實例,但它們相互之間是完全獨立的,它們僅共享JVM的資源。

14. org.apache.catalina. Connector

Connector是一個從客戶端接受請求(request)並生成回應(reponse)的組件。一個Connection通常執行下面的邏輯:

1) 從客戶端程序接受請求

2) 創建Request和Response,並把下面這些屬性設置到這些對象

(1)對所有的Request,connector,protocol,protocol,response,scheme,secure,serverName,serverPort,serverPort屬性必須被設置。contentLength,contentType通常也被設置。

3) 對所有的HttpRequests,method,queryString,requestedSessionCookie,requestedSessionId,requestedSessionURL,requestURI,secure屬性必須被設置。另外所有addXxx方法也必須被調用以記錄cookIEs,headers和locales信息。

4) 對所有的Responses屬性connector,request,stream屬性必須被設置。

對HttpResponses來說,connector不會為它設置額外headers信息。

1. Tomcat整體架構類圖

下篇將從Tomcat的各個組件入手介紹Tomcat。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved