開篇
責任鍊模式:責任鍊模式可以用在這樣的場景,當一個request過來的時候,需要對這個request做一系列的加工,使用責任鍊模式可以使每個加工元件化,減少耦合。也可以使用在當一個request過來的時候,需要找到合适的加工方式。當一個加工方式不适合這個request的時候,傳遞到下一個加工方法,該加工方式再嘗試對request加工。
在tomcat中容器之間的調用使用的就是責任鍊的設計模式,當一個請求過來的時候首先是engine容器接受請求,然後engine容器會把請求傳到host容器,host容器又會傳到context容器,context容器傳到wrapper容器,最後wrapper容器使用适配請求的servlet處理請求。
職責鍊組成
Valve
Valve作為職責鍊上的每個節點,主要用于處理流到該節點的request對象。
說明:
-
- Valve的具體實作的類的一部分如上圖所示。
-
- Valve的抽象類ValveBase包含Valve next元素,也就是每個Value包含指向下一個Valve的對象,類似遞歸。
public interface Valve {
public Valve getNext();
public void setNext(Valve valve);
public void backgroundProcess();
public void invoke(Request request, Response response) throws IOException, ServletException;
public boolean isAsyncSupported();
}
public abstract class ValveBase extends LifecycleMBeanBase implements Contained, Valve {
// 指向下一個Valve對象
protected Valve next = null;
public Valve getNext() {
return next;
}
public void setNext(Valve valve) {
this.next = valve;
}
public void backgroundProcess() {
}
}
final class StandardEngineValve extends ValveBase {
public final void invoke(Request request, Response response)
throws IOException, ServletException {
Host host = request.getHost();
if (host == null) {
response.sendError
(HttpServletResponse.SC_BAD_REQUEST,
sm.getString("standardEngine.noHost",
request.getServerName()));
return;
}
if (request.isAsyncSupported()) {
request.setAsyncSupported(host.getPipeline().isAsyncSupported());
}
host.getPipeline().getFirst().invoke(request, response);
}
}
Pipeline
Pipeline作為職責鍊對象,主要維護Valve職責鍊節點對象。
-
- Pipeline作為職責鍊對象,維護Valve職責鍊對象。
-
- Pipeline包含職責鍊對象的頭節點Valve first和尾節點Valve basic。
public interface Pipeline {
public Valve getBasic();
public void setBasic(Valve valve);
public void addValve(Valve valve);
public Valve[] getValves();
public void removeValve(Valve valve);
public Valve getFirst();
public boolean isAsyncSupported();
public Container getContainer();
public void setContainer(Container container);
public void findNonAsyncValves(Set<String> result);
}
public class StandardPipeline extends LifecycleBase
implements Pipeline, Contained {
public StandardPipeline() {
this(null);
}
public StandardPipeline(Container container) {
super();
setContainer(container);
}
protected Valve basic = null;
protected Container container = null;
protected Valve first = null;
public Valve getBasic() {
return (this.basic);
}
public void setBasic(Valve valve) {
Valve oldBasic = this.basic;
if (oldBasic == valve)
return;
if (oldBasic != null) {
if (getState().isAvailable() && (oldBasic instanceof Lifecycle)) {
try {
((Lifecycle) oldBasic).stop();
} catch (LifecycleException e) {
}
}
if (oldBasic instanceof Contained) {
try {
((Contained) oldBasic).setContainer(null);
} catch (Throwable t) {
}
}
}
if (valve == null)
return;
if (valve instanceof Contained) {
((Contained) valve).setContainer(this.container);
}
if (getState().isAvailable() && valve instanceof Lifecycle) {
try {
((Lifecycle) valve).start();
} catch (LifecycleException e) {
return;
}
}
Valve current = first;
while (current != null) {
if (current.getNext() == oldBasic) {
current.setNext(valve);
break;
}
current = current.getNext();
}
this.basic = valve;
}
public void addValve(Valve valve) {
if (valve instanceof Contained)
((Contained) valve).setContainer(this.container);
if (getState().isAvailable()) {
if (valve instanceof Lifecycle) {
try {
((Lifecycle) valve).start();
} catch (LifecycleException e) {
}
}
}
if (first == null) {
first = valve;
valve.setNext(basic);
} else {
Valve current = first;
while (current != null) {
if (current.getNext() == basic) {
current.setNext(valve);
valve.setNext(basic);
break;
}
current = current.getNext();
}
}
container.fireContainerEvent(Container.ADD_VALVE_EVENT, valve);
}
public Valve getFirst() {
if (first != null) {
return first;
}
return basic;
}
}
職責鍊元素組合關系
-
- 容器StandardEngine包含職責鍊對象StandardPipeline。
-
- StandardPipeline作為職責鍊對象包含職責接地啊Valve對象。
-
- Valve對象有一些具體的實作類如StandardEngineValve對象。
職責鍊調用棧
-
- 每個容器包含職責鍊對象Pipeline。
-
- 每個職責對象Valve的具體實作當中會包含下一個容器對象,相當于Valve對象内部會通路下一個容器,進而實作職責鍊傳遞。
招聘資訊
【招賢納士】
歡迎熱愛技術、熱愛生活的你和我成為同僚,和貝貝共同成長。
貝貝集團誠招算法、大資料、BI、Java、PHP、android、iOS、測試、運維、DBA等人才,有意可投遞
[email protected]。
貝貝集團建立于2011年,旗下擁有貝貝網、貝店、貝貸等平台,緻力于成為全球領先的家庭消費平台。
貝貝創始團隊來自阿裡巴巴,先後獲得IDG資本、高榕資本、今日資本、新天域資本、北極光等數億美金的風險投資。
公司位址:杭州市江幹區普盛巷9号東谷創業園(上下班有多趟班車)