天天看點

tomcat源碼分析-Bootstrap操作Catalina

在閱讀tomcat源碼前,我們一般都會有如下幾個疑問:

web容器和servlet容器的差別是什麼;

在springmvc中的web.xml是什麼時候加載到tomcat中的;

tomcat是怎麼加載我們的web服務的;

tomcat是怎麼實作的熱部署;

一個http請求是怎麼被tomcat監聽到的,會有哪些處理;

為什麼請求可以有需要通過nginx的,也可以不需要nginx的直接請求到tomcat上? ……

如果你想知道答案,那麼接下來的文章會告訴你。

問題先放在一邊,我們都知道tomcat是一種web容器,用來接收http請求,并将請求得到的結果傳回。那麼如果要我們設計一個web容器,該怎麼做? 

很自然的會想到,要有一個網絡連接配接通信維護者和一個請求處理者。通信維護者能夠監聽到請求并傳回資料;請求處理者能夠将請求進行分解處理,得到請求應該傳回的資料。如果你的思路是這樣的,那麼恭喜你,你看源碼會簡單很多,因為tomcat的設計核心就是這樣的,由兩大元件組成:connector和container。connector負責的是底層的網絡通信的實作,而container負責的是上層servlet業務的實作。

也許你會猴急,希望快點知道connector和container是怎麼設計和實作的,不過我要掉你胃口了,先得給你講講tomcat啟動過程,因為隻有知道了tomcat啟動過程,才能對connector和container是怎麼初始化的了然于胸,知道了connector和container的初始化才能準确的把握其結構。

啟動指令行:java [****] org.apache.catalina.startup.boostrap start,從指令行中可知,調用的boostrap類的main方法,main方法參數是start。

從源碼中可以看到,main方法可傳入的參數有 startd、stopd、start、stop,startd和start的差別是設定了一個await的bool變量為true,這點在後面會繼續提到。

通過運作tomcat參數的可以看到main方法主要做了3件事:

執行個體化boostrap對象,并調用其init方法;

調用load方法

調用start方法;

調用boostrap的init方法主要完成三件事:

-(1)初始化路徑:設定home和base路徑,其中home是tomcat安裝目錄,base是tomcat工作目錄;如果我們想要運作tomcat 的 多個執行個體,但是不想安裝多個tomcat軟體副本。那麼我們可以配置多個工作 目錄,每個運作執行個體獨占一個工作目錄,但是共享同一個安裝目錄。

-(2)初始化類加載器:初始化tomcat類加載器:commonloader、catalinaloader、sharedloader

commonloader無父加載器,catalinaloader和sharedloader的父加載器都是commonloader,其中若tomcat的配置檔案沒有配置:server.loader則catalinaloader=commonloader,同理,沒配置shared.loader……,這三種都是urlclassloader,使用java 中的安全模型。

tomcat 的類加載器體系如下結構所示:

tomcat源碼分析-Bootstrap操作Catalina

-(3)初始化boostrap的catalina對象:通過反射生成catalina對象,并通過反射調用setparentclassloader方法設定其父 classloader為sharedloader。為什麼要用反射,個人認為在tomcat的發展曆史上可以不止catalina一種啟動方式,現在看代碼已經沒必要了。

-(4)其他:主線程的classloader設定為catalinaloader,安全管理的classload設定為catalineloader。

調用catalina的load方法:

-(1)判斷系統變量catalina設定home和base路徑是否設定,沒有的話則設定一下

-(2)初始化命名服務的基本配置

-(3)digester類,預設将conf/server.xml解析成相應的對象,這個解析很重要,因為是他完成了connector和container的初始化工作。先mark下,接下來會詳細的介紹digester是怎麼完成connector和container的初始化,現在我們隻要知道是這裡完成的就可以了。

-(4)server調用init初始化聲明周期,其父類lifecyclebase實作

調用catalina的start方法: 

-(1)server加載:server才是正真的tomcat服務執行者,包括connector和container。調用load方法;

-(2)調用server的start方法,最終調用的是standardserver的startinternal方法,調用自己所有的service的start方法,啟動connector和container、excutor的start方法,後文會繼續擴充。

-(3)注冊鈎子

可以看到,boostrap調用catalina的方法時,全部都用的是反射,包括生成catalina對象。而tomcat的啟動說白了其實就是初始化并啟動connector和container。

原文連結:[http://wely.iteye.com/blog/2294760]