在 Tomcat原始碼分析 (二)----- Tomcat整體架構及元件 中我們簡單分析了一下Pipeline和Valve,並給出了整體的結構圖。而這一節,我們將詳細分析Tomcat裡面的原始碼。
Valve
Valve
作為一個個基礎的閥門,扮演著業務實際執行者的角色。我們看看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(); }
Contained
ValveBase
、Pipeline
及其他相關元件都實現了Contained
介面,我們看看這個介面有哪些方法。很簡單,就是get/set容器操作。
public interface Contained { /** * Get the {@link Container} with which this instance is associated. * * @return The Container with which this instance is associated or * <code>null</code> if not associated with a Container */ Container getContainer(); /** * Set the <code>Container</code> with which this instance is associated. * * @param container The Container instance with which this instance is to * be associated, or <code>null</code> to disassociate this instance * from any Container */ void setContainer(Container container); }
ValveBase
從Valve的類層次結構,我們發現幾乎所有Valve都繼承了ValveBase
這個抽象類,所以這兒我們需要分析一下它。
public abstract class ValveBase extends LifecycleMBeanBase implements Contained, Valve { // 國際化管理器,可以支援多國語言 protected static final StringManager sm = StringManager.getManager(ValveBase.class); //------------------------------------------------------ Instance Variables // 無參構造方法,預設不支援非同步 public ValveBase() { this(false); } // 有參構造方法,可傳入非同步支援標記 public ValveBase(boolean asyncSupported) { this.asyncSupported = asyncSupported; } //------------------------------------------------------ Instance Variables // 非同步標記 protected boolean asyncSupported; // 所屬容器 protected Container container = null; // 容器日誌元件物件 protected Log containerLog = null; // 下一個閥門 protected Valve next = null; //-------------------------------------------------------------- Properties // 獲取所屬容器 @Override public Container getContainer() { return container; } // 設定所屬容器 @Override public void setContainer(Container container) { this.container = container; } // 是否非同步執行 @Override public boolean isAsyncSupported() { return asyncSupported; } // 設定是否非同步執行 public void setAsyncSupported(boolean asyncSupported) { this.asyncSupported = asyncSupported; } // 獲取下一個待執行的閥門 @Override public Valve getNext() { return next; } // 設定下一個待執行的閥門 @Override public void setNext(Valve valve) { this.next = valve; } //---------------------------------------------------------- Public Methods // 後臺執行,子類實現 @Override public void backgroundProcess() { // NOOP by default } // 初始化邏輯 @Override protected void initInternal() throws LifecycleException { super.initInternal(); // 設定容器日誌元件物件到當前閥門的containerLog屬性 containerLog = getContainer().getLogger(); } // 啟動邏輯 @Override protected synchronized void startInternal() throws LifecycleException { setState(LifecycleState.STARTING); } // 停止邏輯 @Override protected synchronized void stopInternal() throws LifecycleException { setState(LifecycleState.STOPPING); } // 重寫toString,格式為[${containerName}] @Override public String toString() { StringBuilder sb = new StringBuilder(this.getClass().getName()); sb.append('['); if (container == null) { sb.append("Container is null"); } else { sb.append(container.getName()); } sb.append(']'); return sb.toString(); } // -------------------- JMX and Registration -------------------- // 設定獲取MBean物件的keyProperties,格式如:a=b,c=d,e=f... @Override public String getObjectNameKeyProperties() { StringBuilder name = new StringBuilder("type=Valve"); Container container = getContainer(); name.append(container.getMBeanKeyProperties()); int seq = 0; // Pipeline may not be present in unit testing Pipeline p = container.getPipeline(); if (p != null) { for (Valve valve : p.getValves()) { // Skip null valves if (valve == null) { continue; } // Only compare valves in pipeline until we find this valve if (valve == this) { break; } if (valve.getClass() == this.getClass()) { // Duplicate valve earlier in pipeline // increment sequence number seq ++; } } } if (seq > 0) { name.append(",seq="); name.append(seq); } String className = this.getClass().getName(); int period = className.lastIndexOf('.'); if (period >= 0) { className = className.substring(period + 1); } name.append(",name="); name.append(className); return name.toString(); } // 獲取所屬域,從container獲取 @Override public String getDomainInternal() { Container c = getContainer(); if (c == null) { return null; } else { return c.getDomain(); } } }
Pipeline
Pipeline
作為一個管道,我們可以簡單認為是一個Valve的集合,內部會對這個集合進行遍歷,呼叫每個元素的業務邏輯方法invoke()
。
是不是這樣呢?我們還是分析一下原始碼,先看看介面定義。
public interface Pipeline { // ------------------------------------------------------------- Properties // 獲取基本閥門 public Valve getBasic(); // 設定基本閥門 public void setBasic(Valve valve); // --------------------------------------------------------- Public Methods // 新增閥門 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); // 查詢非非同步執行的所有閥門,並放置到result引數中,所以result不允許為null public void findNonAsyncValves(Set<String> result); }
StandardPipeline
接著我們分析一下Pipeline
唯一的實現StandardPipeline
。程式碼很長,但是都很簡單。
public class StandardPipeline extends LifecycleBase implements Pipeline, Contained { private static final Log log = LogFactory.getLog(StandardPipeline.class); // ----------------------------------------------------------- Constructors // 構造一個沒有所屬容器的管道 public StandardPipeline() { this(null); } // 構造一個有所屬容器的管道 public StandardPipeline(Container container) { super(); setContainer(container); } // ----------------------------------------------------- Instance Variables /** * 基本閥門,最後執行的閥門 */ protected Valve basic = null; /** * 管道所屬的容器 */ protected Container container = null; /** * 管道里面的首個執行的閥門 */ protected Valve first = null; // --------------------------------------------------------- Public Methods // 是否非同步執行,如果一個閥門都沒有,或者所有閥門都是非同步執行的,才返回true @Override public boolean isAsyncSupported() { Valve valve = (first!=null)?first:basic; boolean supported = true; while (supported && valve!=null) { supported = supported & valve.isAsyncSupported(); valve = valve.getNext(); } return supported; } // 查詢所有未非同步執行的閥門 @Override public void findNonAsyncValves(Set<String> result) { Valve valve = (first!=null) ? first : basic; while (valve != null) { if (!valve.isAsyncSupported()) { result.add(valve.getClass().getName()); } valve = valve.getNext(); } } // ------------------------------------------------------ Contained Methods // 獲取所屬容器 @Override public Container getContainer() { return (this.container); } // 設定所屬容器 @Override public void setContainer(Container container) { this.container = container; } // 初始化邏輯,預設沒有任何邏輯 @Override protected void initInternal() { // NOOP } // 開始邏輯,呼叫所有閥門的start方法 @Override protected synchronized void startInternal() throws LifecycleException { // Start the Valves in our pipeline (including the basic), if any Valve current = first; if (current == null) { current = basic; } while (current != null) { if (current instanceof Lifecycle) ((Lifecycle) current).start(); current = current.getNext(); } setState(LifecycleState.STARTING); } // 停止邏輯,呼叫所有閥門的stop方法 @Override protected synchronized void stopInternal() throws LifecycleException { setState(LifecycleState.STOPPING); // Stop the Valves in our pipeline (including the basic), if any Valve current = first; if (current == null) { current = basic; } while (current != null) { if (current instanceof Lifecycle) ((Lifecycle) current).stop(); current = current.getNext(); } } // 銷燬邏輯,移掉所有閥門,呼叫removeValve方法 @Override protected void destroyInternal() { Valve[] valves = getValves(); for (Valve valve : valves) { removeValve(valve); } } /** * 重新toString方法 */ @Override public String toString() { StringBuilder sb = new StringBuilder("Pipeline["); sb.append(container); sb.append(']'); return sb.toString(); } // ------------------------------------------------------- Pipeline Methods // 獲取基礎閥門 @Override public Valve getBasic() { return (this.basic); } // 設定基礎閥門 @Override public void setBasic(Valve valve) { // Change components if necessary Valve oldBasic = this.basic; if (oldBasic == valve) return; // Stop the old component if necessary // 老的基礎閥門會被呼叫stop方法且所屬容器置為null if (oldBasic != null) { if (getState().isAvailable() && (oldBasic instanceof Lifecycle)) { try { ((Lifecycle) oldBasic).stop(); } catch (LifecycleException e) { log.error("StandardPipeline.setBasic: stop", e); } } if (oldBasic instanceof Contained) { try { ((Contained) oldBasic).setContainer(null); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); } } } // Start the new component if necessary // 新的閥門會設定所屬容器,並呼叫start方法 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) { log.error("StandardPipeline.setBasic: start", e); return; } } // Update the pipeline // 替換pipeline中的基礎閥門,就是講基礎閥門的前一個閥門的next指向當前閥門 Valve current = first; while (current != null) { if (current.getNext() == oldBasic) { current.setNext(valve); break; } current = current.getNext(); } this.basic = valve; } // 新增閥門 @Override public void addValve(Valve valve) { // Validate that we can add this Valve // 設定所屬容器 if (valve instanceof Contained) ((Contained) valve).setContainer(this.container); // Start the new component if necessary // 呼叫閥門的start方法 if (getState().isAvailable()) { if (valve instanceof Lifecycle) { try { ((Lifecycle) valve).start(); } catch (LifecycleException e) { log.error("StandardPipeline.addValve: start: ", e); } } } // Add this Valve to the set associated with this Pipeline // 設定閥門,將閥門新增到基礎閥門的前一個 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); } // 獲取閥門陣列 @Override public Valve[] getValves() { ArrayList<Valve> valveList = new ArrayList<>(); Valve current = first; if (current == null) { current = basic; } while (current != null) { valveList.add(current); current = current.getNext(); } return valveList.toArray(new Valve[0]); } // JMX方法,在此忽略 public ObjectName[] getValveObjectNames() { ArrayList<ObjectName> valveList = new ArrayList<>(); Valve current = first; if (current == null) { current = basic; } while (current != null) { if (current instanceof JmxEnabled) { valveList.add(((JmxEnabled) current).getObjectName()); } current = current.getNext(); } return valveList.toArray(new ObjectName[0]); } // 移除閥門 @Override public void removeValve(Valve valve) { Valve current; if(first == valve) { // 如果待移出的閥門是首個閥門,則首個閥門的下一個閥門變成首個閥門 first = first.getNext(); current = null; } else { current = first; } // 遍歷閥門集合,並進行移除 while (current != null) { if (current.getNext() == valve) { current.setNext(valve.getNext()); break; } current = current.getNext(); } if (first == basic) first = null; // 設定閥門所屬容器為null if (valve instanceof Contained) ((Contained) valve).setContainer(null); // 呼叫待移除閥門的stop方法和destroy方法,並觸發移除閥門事件 if (valve instanceof Lifecycle) { // Stop this valve if necessary if (getState().isAvailable()) { try { ((Lifecycle) valve).stop(); } catch (LifecycleException e) { log.error("StandardPipeline.removeValve: stop: ", e); } } try { ((Lifecycle) valve).destroy(); } catch (LifecycleException e) { log.error("StandardPipeline.removeValve: destroy: ", e); } } container.fireContainerEvent(Container.REMOVE_VALVE_EVENT, valve); } // 獲取首個閥門,如果閥門列表為null,返回基礎閥門 @Override public Valve getFirst() { if (first != null) { return first; } return basic; } }
總結
通過上面的程式碼分析,我們發現了幾個關鍵的設計模式:
- 模板方法模式,父類定義框架,子類實現
- 責任鏈模式,就是這兒的管道/閥門的實現方式,每個閥門維護一個next屬性指向下一個閥門