Tomcat中设计模式-职责链

开篇

 责任链模式:责任链模式可以用在这样的场景,当一个request过来的时候,需要对这个request做一系列的加工,使用责任链模式可以使每个加工组件化,减少耦合。也可以使用在当一个request过来的时候,需要找到合适的加工方式。当一个加工方式不适合这个request的时候,传递到下一个加工方法,该加工方式再尝试对request加工。

 在tomcat中容器之间的调用使用的就是责任链的设计模式,当一个请求过来的时候首先是engine容器接受请求,然后engine容器会把请求传到host容器,host容器又会传到context容器,context容器传到wrapper容器,最后wrapper容器使用适配请求的servlet处理请求。


职责链组成

Valve

Valve作为职责链上的每个节点,主要用于处理流到该节点的request对象。

Tomcat中设计模式-职责链

说明:

    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职责链节点对象。
Tomcat中设计模式-职责链

说明:

    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;
    }
}


职责链元素组合关系

Tomcat中设计模式-职责链
说明:

    1. 容器StandardEngine包含职责链对象StandardPipeline。
    1. StandardPipeline作为职责链对象包含职责接地啊Valve对象。
    1. Valve对象有一些具体的实现类如StandardEngineValve对象。


职责链调用栈

Tomcat中设计模式-职责链
说明:

    1. 每个容器包含职责链对象Pipeline。
    1. 每个职责对象Valve的具体实现当中会包含下一个容器对象,相当于Valve对象内部会访问下一个容器,进而实现职责链传递。


招聘信息

【招贤纳士】

欢迎热爱技术、热爱生活的你和我成为同事,和贝贝共同成长。

贝贝集团诚招算法、大数据、BI、Java、PHP、android、iOS、测试、运维、DBA等人才,有意可投递zhi.wang@beibei.com

贝贝集团创建于2011年,旗下拥有贝贝网、贝店、贝贷等平台,致力于成为全球领先的家庭消费平台。

贝贝创始团队来自阿里巴巴,先后获得IDG资本、高榕资本、今日资本、新天域资本、北极光等数亿美金的风险投资。

公司地址:杭州市江干区普盛巷9号东谷创业园(上下班有多趟班车)

上一篇:mysql


下一篇:Netty基础