3 tomcat容器先導篇--管道

一、管道存在意義

認爲管道是連接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、負責解耦容器的請求和調用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章