tomcat + spring mvc 原理(一):tomcat原理綜述和靜態架構

java06051515發表於2020-02-17


tomat + spring mvc 是目前比較流行java微服務體系架構,包括現在的spring boot以及基於spring boot的進一步應用化封裝的spring cloud框架,底層都是基於tomcat + spring mvc的框架。因此學習tomcat + spring mvc的基礎原理,對於解決使用中出現的問題會有比較大的幫助。

tomcat + spring mvc的運作模式

    理解tomcat+spring mvc的工作原理之前,最好能自己配置一下tomcat環境,然後部署一個spring mvc服務,實際感受一下整個流程,對tomcat和spring mvc暴露在外的配置有一個大概的瞭解。這樣有了感性的認識之後,再深入瞭解原理,會有比較好的理解。網上已經有很多比較詳細的關於tomcat環境搭建的文章,這裡我就不再贅述。
    傳統的使用tomcat + spring mvc框架的服務在開發之前,需要先行配置tomcat的環境。這個過程包括下載和安裝tomcat,配置環境變數,修改tomcat的配置檔案,最後執行tomcat。對,你沒看錯,tomcat獨立執行,而spring mvc的服務是tomcat執行時載入的。基於spring mvc框架的服務可以在流行的java IDE中自動建立,比如eclipse或者idea。自動建立的工程基本配置已經寫入,你可以直接動手書寫業務程式碼,這也是這種架構的顯著優勢。當然你也可以建立一個空的專案,自行配置。總的來說,spring mvc基於xml或者java程式碼的config檔案的配置是比較繁瑣的。專案最後需要打包成一個war檔案,複製到tomcat的指定目錄下,tomcat會自動解包載入,然後基於你的配置,訪問指定埠的指定路由連結,就可以請求伺服器的資訊應答。
    顯然,這種運作模式要求:tomcat需要有監視指定目錄,一旦有新的war包加入,就完成解包並動態載入編譯後的class的能力;tomcat需要有網路埠開閉和監視的機制,維護執行緒池來處理隨時可能到來的請求;tomcat還需要將到來的請求順利地傳遞給spring mvc服務,然後再將服務返回的資料傳送出去。

tomcat內部的基本容器構成

    所謂容器(Container),並不是常說的用來儲存資料結構的類,比如Collection、Set、List等,而是專指tomcat和spring mvc中用來對功能和結構進行分層抽象的概念(類或者介面)。tomcat的基本容器結構如圖所示:
server structure
    tomcat最頂層的容器Server,代表整個tomcat伺服器,一個Server可以包含一個或者多個Service。一個Service包含一個或者多個Connetor,但是隻能包含一個Container。Connector主要用來處理連線相關的事,比如網路套接字Socket的監聽、請求request的接收和應答response的傳送。這裡的Container是一個抽象的概念,一個介面。其實是指一個Service只能包含一個Engine--Engine繼承自Container。Engine容器結構如圖所示:
container 結構
其中Engine、Host、Context和Wrapper都繼承自Container。
    Engine用來管理多個站點,即可以有多個Host。Host代表一個站點,其實是一個虛擬主機。Context,上下文,代表一套應用程式,一套應用程式總是有相同的應用上下文配置。最後是Wrapper, 每個wrapper只有一個Servlet,而每個Servlet即對應每個開發的spring mvc服務程式。所以我們開發的spring mvc服務程式都是透過Wrapper載入到tomcat中。Context和Wrapper是動態新增的,我們在tomcat的指定目錄下每新增一個war包,tomcat載入war包時,就可以新增Context和Servlet。

tomcat容器對應的外部配置

    之所以強調學習原理之前,最好先自己配置tomcat環境和部署一個spring mvc服務程式,是因為tomcat的很多配置和內部容器相關。外部感性理解和對內部原理的理性理解的結合,有益於認知的深入和記憶。
    在tomcat的安裝目錄下(使用linux yum安裝的預設目錄在/usr/local/tomcat下,其他系統和安裝方法的目錄需要百度),有一個conf資料夾,裡面存放著一些tomcat層次的容器配置。server.xml配置了Server容器下Service、Connector、Engine和Host的配置,格式類似上圖所顯示的巢狀結構,不過是以xml的形式。以其中一個Connector配置為例:

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />

上面說到Connector主要用來處理連線相關的事,比如網路套接字Socket的監聽、請求request的接收和應答response的傳送。所以這裡就配置了埠、網路協議、連線超時時間和重定向埠。其他容器的配置也比較類似,可以自行開啟瀏覽一下。conf目錄下的context.xml檔案存放Context容器的配置:

<Context>
    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    --></Context>

內部主要包括了兩個web.xml的目錄配置。按照上文所講的容器結構,Context容器可以中可以有一個或者多個Wrapper,每個Wrapper中包含一個Servlet,Servlet就是我們開發的spring mvc 服務程式。web.xml裡寫的是spring mvc Servlet的相關配置,一般的spring mvc專案中會有一個WEB-INF目錄,內部包含一個自己配置的web.xml檔案。另一個是tomcat預設的web.xml的配置,可以看到就是conf目錄下的web.xml,這個預設配置是針對所有部署在tomcat中的spring mvc程式。具體關於web.xml配置內容的解釋,放在後面的spring mvc原理綜述中。


作者:孫新


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559758/viewspace-2675871/,如需轉載,請註明出處,否則將追究法律責任。

相關文章