java web原理

一.tomcat結構


1 - Server

代表一個服務器。

2 - Service

包含多個Connector組件以及一個Engine組件。負責處理所有Connector所獲得的客戶請求。

3 - Connector

一個Connector將在某個指定端口上偵聽客戶請求,並將獲得的請求交給Engine來處理,從Engine處獲得迴應並返回客戶。

TOMCAT有兩個典型的Connector,一個直接偵聽來自browser的http請求,一個偵聽來自其它WebServer的請求。

Coyote Http/1.1 Connector 在端口8080處偵聽來自客戶browser的http請求。

Coyote JK2 Connector 在端口8009處偵聽來自其它WebServer(Apache)的servlet/jsp代理請求。

4 - Engine

Engine下可以配置多個虛擬主機Virtual Host,每個虛擬主機都有一個域名,當Engine獲得一個請求時,它把該請求匹配到某個Host上,然後把該請求交給該Host來處理。

Engine有一個默認虛擬主機,當請求無法匹配到任何一個Host上的時候,將交給該默認Host來處理。

5 - Host

代表一個Virtual Host,虛擬主機,每個虛擬主機和某個網絡域名Domain Name相匹配。每個虛擬主機下都可以部署(deploy)一個或者多個Web App,每個Web App對應於一個Context,有一個Context path。當Host獲得一個請求時,將把該請求匹配到某個Context上,然後把該請求交給該Context來處理。匹配的方法是“最長匹配”,所以一個path==""的Context將成爲該Host的默認Context。所有無法和其它Context的路徑名匹配的請求都將最終和該默認Context匹配。

6 - Context

一個Context對應於一個Web Application,一個Web Application由一個或者多個Servlet組成。Context在創建的時候將根據配置文件$CATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml載入Servlet類。當Context獲得請求時,將在自己的映射表(mapping table)中尋找相匹配的Servlet類,如果找到,則執行該類,獲得請求的迴應,並返回。


二.tomcat啓動過程

1.初始化環境變量,設置Tomcat類加載體系的頂級類加載器(主要是CommonLoader、CatalinaLoader以及SharedLoader)。

附1:java web類加載順序

2.解析server.xml,初始化各個組件(包含各個web應用,解析對應的web.xml進行初始化

由於Tomcat內部設計的問題,整個組件的啓動並不是分散的,父級組件的啓動會帶動子級元素組件的啓動,依次類推,會使整個組件都啓動起來,例如Server的啓動會使相關的Service組件都啓動,而Service的啓動又會帶動Connector的啓動等等。

附2:web應用加載過程

3.初始化連接器:初始化聲明的Connector,以指定的協議打開端口,等待請求。


三.tomcat工作原理

tomcat就是一個典型的web 容器,當瀏覽器向服務器發送一個請求時,該請求會發送給web容器,web容器的作用就是選擇合適的資源處理該請求(servlet或者jsp)。並將結果封裝並返回給web服務器,然後web服務器將響應內容返回給客戶端。

如果web容器收到請求後發現該請求需要由一個servlet處理,則web容器會創建兩個對象:HttpServletRequest和HttpServletResponse,然後它基於url找到合適的servlet,併爲該請求創建一個線程。然後web容器將調用servlet的service方法。service方法將根據請求類型調用doXXX方法(比如get請求,將會調用doget方法)。servlet方法生成動態頁面並返將其寫入response中。一旦servlet線程工作完成後,容器便會將response轉化爲httpresponse並返回給瀏覽器。

附3:Tomcat Server處理一個http請求的過程


附1:java web類加載順序

在Java中,類加載器是以一種父子關係樹來組織的。除Bootstrap外,都會包含一個parent 類加載器。一般以類加載器需要加載一個class或者資源文件的時候,他會先委託給他的parent類加載器,讓parent類加載器先來加載,如果沒有,纔再在自己的路徑上加載。這就是人們常說的雙親委託,即把類加載的請求委託給parent。需要注意一下,對於Web應用的類加載,和雙親委託是有所區別的。

在tomcat7.x裏,ClassLoader的模型應該是下圖這樣: 


jvm默認定義了三種classloader,分別是bootstrapclassloader、extension classloader、system classloader

 bootstrap是jvm的一部分,用C寫的,每一個java程序都會啓動它,去加載%JAVA_HOME%/jre/lib/rt.jar,

 extension也差不多,它會去加載%JAVA_HOME%/jre/lib/ext/下的類,

 system則是會去加載系統變量CLASSPATH下的所有類。

這3個部分,在上面的tomcat classloader模型圖中都有體現。不過可以看到extension沒有畫出來,可以理解爲是跟bootstrap合併了,都是去%JAVA_HOME%/jre/lib下面加載類

Common — 這個classloader加載的類,對tomcat的類和web app的類都是可見的。通常來說,應用程序的類不應該放在這裏。該加載器的加載路徑是在$CATALINA_BASE/conf/catalina.properties文件裏,通過common.loader屬性來定義的。

WebappX — 該classloader加載所有WEB-INF/classes裏的類,以及WEB-INF/lib裏的jar。

 該classloader就有意違反了上述的委託模型,它首先看WEB-INF/classes和WEB-INF/lib裏是否有請求的類,而不是委託parentclassloader去加載。但是,JRE裏定義的類不能被覆蓋(比如java.lang.String),以及Servlet API會明確地被忽略。前面說的bootstrap、system、common,都遵循普通的委託模型。


附2:web應用加載過程

1.啓動WEB項目的時候,容器(如:Tomcat)會去讀它的配置文件web.xml.讀兩個節點:  

  <listener></listener> 和<context-param></context-param>

2.緊接着,容器創建一個ServletContext(上下文),這個WEB項目所有部分都將共享這個上下文.

3.容器將<context-param></context-param>轉化爲鍵值對,並交給ServletContext.

4.容器創建<listener></listener>中的類實例,即創建監聽.

5.在監聽中會有contextInitialized(ServletContextEvent args)初始化方法,在這個方法中獲得:

  ServletContext = ServletContextEvent.getServletContext();  

  context-param的值= ServletContext.getInitParameter("context-param的鍵"); 

6.得到這個context-param的值之後,你就可以做一些操作了.注意,這個時候你的WEB項目還沒有完全啓動完成.這個動作會比 所 有的Servlet都要早.

換句話說,這個時候,你對<context-param>中的鍵值做的操作,將在你的WEB項目完全啓動之前被執行.

舉例.你可能想在項目啓動之前就打開數據庫,那麼這裏就可以在<context-param>中設置數據庫的連接方式,在監聽類中初始化數據庫的連接。這個監聽是自己寫的一個類,除了初始化方法,它還有銷燬方法,用於關閉應用前釋放資源.比如說數據庫連接的關閉。


附3:Tomcat Server處理一個http請求的過程

假設來自客戶的請求爲:

http://localhost:8080/wsota/wsota_index.jsp

1) 請求被髮送到本機端口8080,被在那裏偵聽的Coyote HTTP/1.1 Connector獲得

2) Connector把該請求交給它所在的Service的Engine來處理,並等待來自Engine的迴應

3) Engine獲得請求localhost/wsota/wsota_index.jsp,匹配它所擁有的所有虛擬主機Host

4) Engine匹配到名爲localhost的Host(即使匹配不到也把請求交給該Host處理,因爲該Host被定義爲該Engine的默認主機)

5) localhost Host獲得請求/wsota/wsota_index.jsp,匹配它所擁有的所有Context

6) Host匹配到路徑爲/wsota的Context(如果匹配不到就把該請求交給路徑名爲""的Context去處理)

7) path="/wsota"的Context獲得請求/wsota_index.jsp,在它的mapping table中尋找對應的servlet

8) Context匹配到URL PATTERN爲*.jsp的servlet,對應於JspServlet類

9) 構造HttpServletRequest對象和HttpServletResponse對象,作爲參數調用JspServlet的doGet或doPost方法

10)Context把執行完了之後的HttpServletResponse對象返回給Host

11)Host把HttpServletResponse對象返回給Engine

12)Engine把HttpServletResponse對象返回給Connector

13)Connector把HttpServletResponse對象返回給客戶browser



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章