之前的博文介紹了tomcat有兩大核心組件,connector和container,connector負責接受外部請求,container負責處理請求,本文從源碼的角度介紹container的整體架構。 一、容器分類 tomcat容器為四個: Engine:代表容器引擎,管理多個虛擬站點,一個Ser ...
之前的博文介紹了tomcat有兩大核心組件,connector和container,connector負責接受外部請求,container負責處理請求,本文從源碼的角度介紹container的整體架構。
一、容器分類
tomcat容器為四個:
- Engine:代表容器引擎,管理多個虛擬站點,一個Service只有一個Engine
- Host:代表虛擬主機
- Context:代表一個web站點
- Wrapper:代表一個servlet
二、容器的結構
以上四大容器是父子關係,但是統一實現了Container介面:
public interface Container extends Lifecycle {
public Pipeline getPipeline(); public Container getParent(); public void setParent(Container container); public void backgroundProcess(); public void addChild(Container child); public Container findChild(String name); public Container[] findChildren(); public void removeChild(Container child); }
實現了統一介面,所以整體使用組合模式來進行組裝和運轉。
三、容器Pipeline、Valve(容器的執行鏈)
在Container的介面定義中有個Pippeline,這個就是當前容器的執行鏈,當執行到這個容器時,實際是執行這個pipeline進行實際的操作。
Pipeline介面定義
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); }
Pipeline猶如一個鏈表,valve是其中的每一個節點(也是具體的執行單元),其中getFirst返回第一個節點,getBasic返回最後一個節點。
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; }
每一個Valve執行完畢後會調用getNext把請求傳給下一個Valve。
BasicValve會調用子容器的getFirst節點把請求傳給子容器。
上一篇博文中代碼可以看到adapter是調用Engine的getFirst把請求傳遞到容器的。
整體過程
其中有一點需要說明的是BasicValve用於是pipeline的最後一個Valve。代碼做了保證(setBasic方法)。