一萄凤、tomcat組件關(guān)系和請求流轉(zhuǎn)
? 先上一張圖谎碍,看之前可以先參考“tomcat整體架構(gòu)”一文
-
動態(tài)生命周期管理
- 讓一個系統(tǒng)能夠?qū)ν馓峁┓?wù)鲤脏,我們需要創(chuàng)建爽茴、組裝并啟動這些組件灾锯;
- 服務(wù)停止的時候兢榨,我們還需要 釋放資源,銷毀這些組件
-
組件關(guān)系的兩個維度思考
- 大小關(guān)系顺饮,大組件管理小組件如Server管理service吵聪,service管理connector和container等等
- 內(nèi)外關(guān)系,外層組件控制內(nèi)層組件兼雄,如連接器負(fù)責(zé)對外又調(diào)用內(nèi)層容器組件完成業(yè)務(wù)處理
-
系統(tǒng)創(chuàng)建組件順序
- 先創(chuàng)建子組件再創(chuàng)建父組件吟逝,子組件需要注入到父組件內(nèi)部
- 先創(chuàng)建內(nèi)層組件再創(chuàng)建外層組件,內(nèi)層組件要注入到外層組件內(nèi)部
二赦肋、tomcat生命周期管理
-
一鍵式啟停: Lifecycle 接口
- 不變點抽象块攒,組件的生命周期無非就是init、start佃乘、stop囱井、destory這些過程,這些過程都是一樣的統(tǒng)一放到一個接口里也就是Lifecycle接口里
- 變化點是具體的init和start過程趣避,每個組件可以單獨實現(xiàn)
- 父組件的init方法需要先調(diào)用子組件的init讓子組件先初始化庞呕,父組件的start方法需要先調(diào)用子組件的start方法讓子組件先啟動,這是典型的組合模式
-
整個的啟動過程就是先調(diào)用server的init和start方法整個tomcat就可以啟動起來了
生命周期接口.png
可擴(kuò)展性:Lifecycle 事件
每個組件的具體init或start過程可能都是多變的程帕,可能會不斷增加邏輯住练,直接修改原來的方法違反開閉原則
開閉原則說的是為了擴(kuò)展系統(tǒng)的功能,你不能直接修改系統(tǒng)中已有的類愁拭,但是你可以定義新的類
組件的啟動過程是有狀態(tài)的讲逛,可以將生命周期定義成一個個的狀態(tài),狀態(tài)的變化可以看成一個事件岭埠,而在事件上是可以加監(jiān)聽器妆绞。監(jiān)聽器可以自由擴(kuò)展和配置,這就是典型的觀察者模式tomcat就是這樣干的
-
組件的生命周期有 NEW枫攀、INITIALIZING、INITIALIZED株茶、STARTING_PREP来涨、STARTING、STARTED 等启盛,具體怎么配置監(jiān)聽器可以自己研讀源碼蹦掐,或者以后單獨再說
組件狀態(tài)轉(zhuǎn)換與生命周期.png 重用性:LifecycleBase 抽象基類
有了接口就需要子類去實現(xiàn)技羔,一般來說可能會有多個實現(xiàn)類,此時必然有一些通用的邏輯卧抗,如果都分開實現(xiàn)會有代碼重復(fù)藤滥,可以先定義一個抽象基類,來實現(xiàn)接口的通用邏輯社裆。各個子類子類集成抽象基類并實現(xiàn)它拙绊。其實這就是模板方法模式
tomcat定義了一個抽象基類LifecycleBase 來實現(xiàn) Lifecycle 接口把一些公共的邏輯放到基類中去,比如生命狀態(tài)的轉(zhuǎn)變與維護(hù)泳秀、生命事件的觸發(fā)以及監(jiān)聽器的添加和刪除等标沪。
子類就負(fù)責(zé)實現(xiàn)自己的初始化、啟動和停止等方法
-
為了避免跟基類中的方法同名嗜傅,我們把具體子類的實現(xiàn)方法改個名字金句,在后面加上 Internal,叫 initInternal吕嘀、startInternal 等
lifebase基類.png
監(jiān)聽器如何注冊
Tomcat 自定義了一些監(jiān)聽器违寞,這些監(jiān)聽器是父組件在創(chuàng)建子組件的過程中注冊到子組件的。比如 MemoryLeakTrackingListener 監(jiān)聽器偶房,用來檢測 Context 容器中的內(nèi)存泄漏趁曼,這個監(jiān)聽器是 Host 容器在創(chuàng)建 Context 容器時注冊到 Context 中的。
還可以在server.xml中定義自己的監(jiān)聽器蝴悉,Tomcat 在啟動時會解析server.xml彰阴,創(chuàng)建監(jiān)聽器并注冊到容器組件
-
總體類圖
生命周期整體類圖.png StandardServer、StandardService 等是 Server 和 Service 組件的具體實現(xiàn)類拍冠,它們都繼承了 LifecycleBase
StandardEngine尿这、StandardHost、StandardContext 和 StandardWrapper 是相應(yīng)容器組件的具體實現(xiàn)類庆杜,因為它們都是容器射众,所以繼承了 ContainerBase 抽象基類,而 ContainerBase 實現(xiàn)了 Container 接口晃财,也繼承了 LifecycleBase 類叨橱,它們的生命周期管理接口和功能接口是分開的,這也符合設(shè)計中接口分離的原則
三断盛、精華總結(jié)
Tomcat 為了實現(xiàn)一鍵式啟停以及優(yōu)雅的生命周期管理罗洗,并考慮到了可擴(kuò)展性和可重用性,將面向?qū)ο笏枷牒驮O(shè)計模式發(fā)揮到了極致钢猛,分別運用了組合模式伙菜、觀察者模式、骨架抽象類和模板方法命迈。
如果你需要維護(hù)一堆具有父子關(guān)系的實體贩绕,可以考慮使用組合模式
當(dāng)一個事件發(fā)生后火的,需要執(zhí)行一連串更新操作,這時候就可以考慮用觀察者模式
模板方法在抽象基類中經(jīng)常用到淑倾,將通用方法抽象到父類馏鹤,子類實現(xiàn)自己獨特業(yè)務(wù)