一、管道存在意義
認爲管道是連接Connector與Servlet的關鍵組件,我們可以把管道想象成一個流水線,每個容器都持有一個子流水線,整個調用流程如圖:
可以看到,連接器處理好數據到調用Servlet的service,經過了哪些容器的管道,這些管道組裝在一起,彷彿就是一個大管道直接連通connector與Servlet。
繼續看看每個容器管道是怎麼進來怎麼出去的。
先看下管道接口的結構
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();
}
這裏面使用到一個組件閥Valve,我們來看看Valve
public interface Valve {
public String getInfo();
public Valve getNext();
public void setNext(Valve valve);
public void backgroundProcess();
public void invoke(Request request, Response response) throws IOException, ServletException;
public void event(Request request, Response response, CometEvent event) throws IOException, ServletException;
}
每個管道都有一個基礎閥,看一下管道的調用方式和閥的使用方式
pipeline.getFirst().invoke(request,response);
void invoke(request, response){
getNext().invoke(request,response);
// 該閥需要處理的工作
}
我們可以大致知道,pipeline管道使用了責任鏈的模式,解耦了請求與處理邏輯,可靈活增加業務邏輯對現有代碼沒有侵入。
而pipeline就是管理着有着前後關係的Valve。
我們可以看下StandardPipeline類的addValve與getFirst()
public void addValve(Valve valve) {
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();
}
}
}
public Valve getFirst() {
if (first != null) {
return first;
} else {
return basic;
}
}
從上面代碼我們可以看出,pipeline維持一個調用鏈,每個管道至少有一個基礎閥。
使用了這種模式,我們可以做到每個閥的職責單一,可靈活添加業務。
至此我們對管道有了大概的認識
1、管道負責容器的串聯
2、負責解耦容器的請求和調用