日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Tomcat 系統(tǒng)架構(gòu)與設(shè)計(jì)模式,第 2 部分: 設(shè)計(jì)模

系統(tǒng) 2330 0

簡(jiǎn)介: ?這個(gè)分為兩個(gè)部分的系列文章研究了 Apache Tomcat 服務(wù)器的系統(tǒng)架構(gòu)以及其運(yùn)用的很多經(jīng)典設(shè)計(jì)模式。 第 1 部分 ?分析了 Tomcat 的工作原理,第 2 部分將分析 Tomcat 中運(yùn)用的許多經(jīng)典設(shè)計(jì)模式,如模版模式、工廠模式和單例模式等。通過(guò)學(xué)習(xí)它們的實(shí)踐運(yùn)用能給我們以后的軟件設(shè)計(jì)起到一定的借鑒作用。

門面設(shè)計(jì)模式

門面設(shè)計(jì)模式在 Tomcat 中有多處使用,在 Request 和 Response 對(duì)象封裝中、Standard Wrapper 到 ServletConfig 封裝中、ApplicationContext 到 ServletContext 封裝中等都用到了這種設(shè)計(jì)模式。

門面設(shè)計(jì)模式的原理

這么多場(chǎng)合都用到了這種設(shè)計(jì)模式,那這種設(shè)計(jì)模式究竟能有什么作用呢?顧名思義,就是將一個(gè)東西封裝成一個(gè)門面好與人家更容易進(jìn)行交流,就像一個(gè)國(guó)家的外交部一樣。

這種設(shè)計(jì)模式主要用在一個(gè)大的系統(tǒng)中有多個(gè)子系統(tǒng)組成時(shí),這多個(gè)子系統(tǒng)肯定要涉及到相互通信,但是每個(gè)子系統(tǒng)又不能將自己的內(nèi)部數(shù)據(jù)過(guò)多的暴露給其它系統(tǒng),不然就沒(méi)有必要?jiǎng)澐肿酉到y(tǒng)了。每個(gè)子系統(tǒng)都會(huì)設(shè)計(jì)一個(gè)門面,把別的系統(tǒng)感興趣的數(shù)據(jù)封裝起來(lái),通過(guò)這個(gè)門面來(lái)進(jìn)行訪問(wèn)。這就是門面設(shè)計(jì)模式存在的意義。

門面設(shè)計(jì)模式示意圖如下:


圖 1. 門面示意圖
圖 1. 門面示意圖 ?

Client 只能訪問(wèn)到 Fa?ade 中提供的數(shù)據(jù)是門面設(shè)計(jì)模式的關(guān)鍵,至于 Client 如何訪問(wèn) Fa?ade 和 Subsystem 如何提供 Fa?ade 門面設(shè)計(jì)模式并沒(méi)有規(guī)定死。

Tomcat 的門面設(shè)計(jì)模式示例

Tomcat 中門面設(shè)計(jì)模式使用的很多,因?yàn)?Tomcat 中有很多不同組件,每個(gè)組件要相互交互數(shù)據(jù),用門面模式隔離數(shù)據(jù)是個(gè)很好的方法。

下面是 Request 上使用的門面設(shè)計(jì)模式:


圖 2. Request 的門面設(shè)計(jì)模式類圖
圖 2. Request 的門面設(shè)計(jì)模式類圖 ?

從圖中可以看出 HttpRequestFacade 類封裝了 HttpRequest 接口能夠提供數(shù)據(jù),通過(guò) HttpRequestFacade 訪問(wèn)到的數(shù)據(jù)都被代理到 HttpRequest 中,通常被封裝的對(duì)象都被設(shè)為 Private 或者 Protected 訪問(wèn)修飾,以防止在 Fa?ade 中被直接訪問(wèn)。

?

觀察者設(shè)計(jì)模式

這種設(shè)計(jì)模式也是常用的設(shè)計(jì)方法通常也叫發(fā)布 - 訂閱模式,也就是事件監(jiān)聽(tīng)機(jī)制,通常在某個(gè)事件發(fā)生的前后會(huì)觸發(fā)一些操作。

觀察者模式的原理

觀察者模式原理也很簡(jiǎn)單,就是你在做事的時(shí)候旁邊總有一個(gè)人在盯著你,當(dāng)你做的事情是它感興趣的時(shí)候,它就會(huì)跟著做另外一些事情。但是盯著你的人必須要到你那去登記,不然你無(wú)法通知它。觀察者模式通常包含下面這幾個(gè)角色:

  • Subject 就是抽象主題:它負(fù)責(zé)管理所有觀察者的引用,同時(shí)定義主要的事件操作。
  • ConcreteSubject 具體主題:它實(shí)現(xiàn)了抽象主題的所有定義的接口,當(dāng)自己發(fā)生變化時(shí),會(huì)通知所有觀察者。
  • Observer 觀察者:監(jiān)聽(tīng)主題發(fā)生變化相應(yīng)的操作接口。

Tomcat 的觀察者模式示例

Tomcat 中觀察者模式也有多處使用,前面講的控制組件生命周期的 Lifecycle 就是這種模式的體現(xiàn),還有對(duì) Servlet 實(shí)例的創(chuàng)建、Session 的管理、Container 等都是同樣的原理。下面主要看一下 Lifecycle 的具體實(shí)現(xiàn)。

Lifecycle 的觀察者模式結(jié)構(gòu)圖:


圖 3. Lifecycle 的觀察者模式結(jié)構(gòu)圖
圖 3. Lifecycle 的觀察者模式結(jié)構(gòu)圖 ?

上面的結(jié)構(gòu)圖中,LifecycleListener 代表的是抽象觀察者,它定義一個(gè) lifecycleEvent 方法,這個(gè)方法就是當(dāng)主題變化時(shí)要執(zhí)行的方法。 ServerLifecycleListener 代表的是具體的觀察者,它實(shí)現(xiàn)了 LifecycleListener 接口的方法,就是這個(gè)具體的觀察者具體的實(shí)現(xiàn)方式。Lifecycle 接口代表的是抽象主題,它定義了管理觀察者的方法和它要所做的其它方法。而 StandardServer 代表的是具體主題,它實(shí)現(xiàn)了抽象主題的所有方法。這里 Tomcat 對(duì)觀察者做了擴(kuò)展,增加了另外兩個(gè)類:LifecycleSupport、LifecycleEvent,它們作為輔助類擴(kuò)展了觀察者的功能。LifecycleEvent 使得可以定義事件類別,不同的事件可區(qū)別處理,更加靈活。LifecycleSupport 類代理了主題對(duì)多觀察者的管理,將這個(gè)管理抽出來(lái)統(tǒng)一實(shí)現(xiàn),以后如果修改只要修改 LifecycleSupport 類就可以了,不需要去修改所有具體主題,因?yàn)樗芯唧w主題的對(duì)觀察者的操作都被代理給 LifecycleSupport 類了。這可以認(rèn)為是觀察者模式的改進(jìn)版。

LifecycleSupport 調(diào)用觀察者的方法代碼如下:


清單 1. LifecycleSupport 中的 fireLifecycleEvent 方法

            				

public void fireLifecycleEvent(String type, Object data) {

    LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);

    LifecycleListener interested[] = null;

    synchronized (listeners) {

        interested = (LifecycleListener[]) listeners.clone();

    }

    for (int i = 0; i < interested.length; i++)

        interested[i].lifecycleEvent(event);

}


          

?

主題是怎么通知觀察者呢?看下面代碼:


清單 2. 容器中的 start 方法

            				

public void start() throws LifecycleException {

    lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);

    lifecycle.fireLifecycleEvent(START_EVENT, null);

    started = true;

    synchronized (services) {

        for (int i = 0; i < services.length; i++) {

            if (services[i] instanceof Lifecycle)

                ((Lifecycle) services[i]).start();

            }

        }

    lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);

}


          

?

?

命令設(shè)計(jì)模式

前面把 Tomcat 中兩個(gè)核心組件 Connector 和 Container,比作一對(duì)夫妻。男的將接受過(guò)來(lái)的請(qǐng)求以命令的方式交給女主人。對(duì)應(yīng)到 Connector 和 Container,Connector 也是通過(guò)命令模式調(diào)用 Container 的。

命令模式的原理

命令模式主要作用就是封裝命令,把發(fā)出命令的責(zé)任和執(zhí)行命令的責(zé)任分開(kāi)。也是一種功能的分工。不同的模塊可以對(duì)同一個(gè)命令做出不同解釋。

下面是命令模式通常包含下面幾個(gè)角色:

  • Client:創(chuàng)建一個(gè)命令,并決定接受者
  • Command 命令:命令接口定義一個(gè)抽象方法
  • ConcreteCommand:具體命令,負(fù)責(zé)調(diào)用接受者的相應(yīng)操作
  • Invoker 請(qǐng)求者:負(fù)責(zé)調(diào)用命令對(duì)象執(zhí)行請(qǐng)求
  • Receiver 接受者:負(fù)責(zé)具體實(shí)施和執(zhí)行一次請(qǐng)求

Tomcat 中的命令模式的示例

Tomcat 中命令模式在 Connector 和 Container 組件之間有體現(xiàn),Tomcat 作為一個(gè)應(yīng)用服務(wù)器,無(wú)疑會(huì)接受到很多請(qǐng)求,如何分配和執(zhí)行這些請(qǐng)求是必須的功能。

下面看一下 Tomcat 是如何實(shí)現(xiàn)命令模式的,下面是 Tomcat 命令模式的結(jié)構(gòu)圖:


圖 4. Tomcat 命令模式的結(jié)構(gòu)圖
圖 4. Tomcat 命令模式的結(jié)構(gòu)圖 ?

Connector 作為抽象請(qǐng)求者,HttpConnector 作為具體請(qǐng)求者。HttpProcessor 作為命令。Container 作為命令的抽象接受者,ContainerBase 作為具體的接受者。客戶端就是應(yīng)用服務(wù)器 Server 組件了。Server 首先創(chuàng)建命令請(qǐng)求者 HttpConnector 對(duì)象,然后創(chuàng)建命令 HttpProcessor 命令對(duì)象。再把命令對(duì)象交給命令接受者 ContainerBase 容器來(lái)處理命令。命令的最終是被 Tomcat 的 Container 執(zhí)行的。命令可以以隊(duì)列的方式進(jìn)來(lái),Container 也可以以不同的方式來(lái)處理請(qǐng)求,如 HTTP1.0 協(xié)議和 HTTP1.1 的處理方式就會(huì)不同。

?

責(zé)任鏈模式

Tomcat 中一個(gè)最容易發(fā)現(xiàn)的設(shè)計(jì)模式就是責(zé)任鏈模式,這個(gè)設(shè)計(jì)模式也是 Tomcat 中 Container 設(shè)計(jì)的基礎(chǔ),整個(gè)容器的就是通過(guò)一個(gè)鏈連接在一起,這個(gè)鏈一直將請(qǐng)求正確的傳遞給最終處理請(qǐng)求的那個(gè) Servlet。

責(zé)任鏈模式的原理

責(zé)任鏈模式,就是很多對(duì)象有每個(gè)對(duì)象對(duì)其下家的引用而連接起來(lái)形成一條鏈,請(qǐng)求在這條鏈上傳遞,直到鏈上的某個(gè)對(duì)象處理此請(qǐng)求,或者每個(gè)對(duì)象都可以處理請(qǐng)求,并傳給下一家,直到最終鏈上每個(gè)對(duì)象都處理完。這樣可以不影響客戶端而能夠在鏈上增加任意的處理節(jié)點(diǎn)。

通常責(zé)任鏈模式包含下面幾個(gè)角色:

  • Handler(抽象處理者):定義一個(gè)處理請(qǐng)求的接口
  • ConcreteHandler(具體處理者):處理請(qǐng)求的具體類,或者傳給下家

Tomcat 中責(zé)任鏈模式示例

在 tomcat 中這種設(shè)計(jì)模式幾乎被完整的使用,tomcat 的容器設(shè)置就是責(zé)任鏈模式,從 Engine 到 Host 再到 Context 一直到 Wrapper 都是通過(guò)一個(gè)鏈傳遞請(qǐng)求。

Tomcat 中責(zé)任鏈模式的類結(jié)構(gòu)圖如下:


圖 5. Tomcat 責(zé)任鏈模式的結(jié)構(gòu)圖
圖 5. Tomcat 責(zé)任鏈模式的結(jié)構(gòu)圖 ?

上圖基本描述了四個(gè)子容器使用責(zé)任鏈模式的類結(jié)構(gòu)圖,對(duì)應(yīng)的責(zé)任鏈模式的角色,Container 扮演抽象處理者角色,具體處理者由 StandardEngine 等子容器扮演。與標(biāo)準(zhǔn)的責(zé)任鏈不同的是,這里引入了 Pipeline 和 Valve 接口。他們有什么作用呢?

實(shí)際上 Pipeline 和 Valve 是擴(kuò)展了這個(gè)鏈的功能,使得在鏈往下傳遞過(guò)程中,能夠接受外界的干預(yù)。Pipeline 就是連接每個(gè)子容器的管子,里面?zhèn)鬟f的 Request 和 Response 對(duì)象好比管子里流的水,而 Valve 就是這個(gè)管子上開(kāi)的一個(gè)個(gè)小口子,讓你有機(jī)會(huì)能夠接觸到里面的水,做一些額外的事情。

為了防止水被引出來(lái)而不能流到下一個(gè)容器中,每一段管子最后總有一個(gè)節(jié)點(diǎn)保證它一定能流到下一個(gè)子容器,所以每個(gè)容器都有一個(gè) StandardXXXValve。只要涉及到這種有鏈?zhǔn)绞翘幚砹鞒踢@是一個(gè)非常值得借鑒的模式。

?

參考資料

學(xué)習(xí)

轉(zhuǎn)載自 http://www.ibm.com/developerworks/cn/java/j-lo-tomcat2/

Tomcat 系統(tǒng)架構(gòu)與設(shè)計(jì)模式,第 2 部分: 設(shè)計(jì)模式分析


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 望谟县| 白水县| 南丰县| 尖扎县| 海安县| 普兰店市| 依安县| 定襄县| 平利县| 淳化县| 东兰县| 虎林市| 基隆市| 广元市| 灌云县| 罗田县| 汪清县| 麦盖提县| 台前县| 平谷区| 福泉市| 静乐县| 邵东县| 永平县| 松原市| 毕节市| 临泽县| 大同县| 平江县| 彭山县| 务川| 饶阳县| 澳门| 抚顺市| 汝城县| 莒南县| 上蔡县| 灯塔市| 华坪县| 荥阳市| 中宁县|