天天看點

Tomcat中設計模式-職責鍊

開篇

 責任鍊模式:責任鍊模式可以用在這樣的場景,當一個request過來的時候,需要對這個request做一系列的加工,使用責任鍊模式可以使每個加工元件化,減少耦合。也可以使用在當一個request過來的時候,需要找到合适的加工方式。當一個加工方式不适合這個request的時候,傳遞到下一個加工方法,該加工方式再嘗試對request加工。

 在tomcat中容器之間的調用使用的就是責任鍊的設計模式,當一個請求過來的時候首先是engine容器接受請求,然後engine容器會把請求傳到host容器,host容器又會傳到context容器,context容器傳到wrapper容器,最後wrapper容器使用适配請求的servlet處理請求。

職責鍊組成

Valve

 Valve作為職責鍊上的每個節點,主要用于處理流到該節點的request對象。

說明:

    1. Valve的具體實作的類的一部分如上圖所示。
    1. 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職責鍊節點對象。

    1. Pipeline作為職責鍊對象,維護Valve職責鍊對象。
    1. 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;
    }
}           

職責鍊元素組合關系

    1. 容器StandardEngine包含職責鍊對象StandardPipeline。
    1. StandardPipeline作為職責鍊對象包含職責接地啊Valve對象。
    1. Valve對象有一些具體的實作類如StandardEngineValve對象。

職責鍊調用棧

    1. 每個容器包含職責鍊對象Pipeline。
    1. 每個職責對象Valve的具體實作當中會包含下一個容器對象,相當于Valve對象内部會通路下一個容器,進而實作職責鍊傳遞。

招聘資訊

【招賢納士】

歡迎熱愛技術、熱愛生活的你和我成為同僚,和貝貝共同成長。

貝貝集團誠招算法、大資料、BI、Java、PHP、android、iOS、測試、運維、DBA等人才,有意可投遞

[email protected]

貝貝集團建立于2011年,旗下擁有貝貝網、貝店、貝貸等平台,緻力于成為全球領先的家庭消費平台。

貝貝創始團隊來自阿裡巴巴,先後獲得IDG資本、高榕資本、今日資本、新天域資本、北極光等數億美金的風險投資。

公司位址:杭州市江幹區普盛巷9号東谷創業園(上下班有多趟班車)