Tomcat详解(4)---Pipeline-Value 管道

4 Pipeline-Value 管道

Container 处理请求是使用Pipeline-Value 管道来处理的

4.1 Pipeline-Value 处理模式

  Pipeline-Value 是责任链模式,责任链模式是指在一个请求处理的过程中有多个处理者依次对请求进行处理,每个处理者负责做自己相应的处理,处理完成后将处理后的请求返回,再让下一个处理者继续处理,就好像驾车的过程中可能会遇到很多次交警检查,可能有查酒驾的也可能有查违章的,在一次驾车的过程中可能会遇到多次检查,这就是责任链模式,Pipeline 就相当于驾车的过程, Value 相当于检查的交警。
  不过Pipeline-Value 的管道模型和普通的责任链模式稍微有点不同,区别主要有两点:

  • 每个Pipeline 都有特定的Value ,而且是在管道的最后一个执行,这个Value 叫BaseValue,Base Value 是不可删除的;
  • 在上层容器的管道的BaseValue 中会调用下层容器的管道。4 个容器的BaseValue 分别是Standard Engine Valve 、StandardHostValve 、StandardContextValve 和StandardWrapperValve,整个处理的流程如下图:
    这里写图片描述

4.2 Pipeline-Value 的实现方法

  Pipeline 管道的实现分为生命周期管理和处理请求两部分,下面分别介绍。
  Pipeline 管道生命周期的实现方法
  Container 中的Pipeline 在抽象实现类ContainerBase 中定义,并在生命周期的startlntemal 、stoplntemal 、destroyInternal 方法中调用管道的相应生命周期方法(因为管道不需要初始化所以initlntemal 方法中并没有调用),代码如下:

  @Override
    protected synchronized void startInternal() throws LifecycleException {
        ...

        // Start the Valves in our pipeline (including the basic), if any
        if (pipeline instanceof Lifecycle)
            ((Lifecycle) pipeline).start();

        ...

    }
     @Override
    protected synchronized void stopInternal() throws LifecycleException {

        ...

        // Stop the Valves in our pipeline (including the basic), if any
        if (pipeline instanceof Lifecycle &&
                ((Lifecycle) pipeline).getState().isAvailable()) {
            ((Lifecycle) pipeline).stop();
        }

        ...
    }
    @Override
    protected void destroyInternal() throws LifecycleException {

        ...
        // Stop the Valves in our pipeline (including the basic), if any
        if (pipeline instanceof Lifecycle) {
            ((Lifecycle) pipeline).destroy();
        }
        ...
    }

  Container 的4 个子容器都继承向ContainerBase ,所以4 个子容器在执行生命周期的方法时都会调用管道相应的生命周期方法。
  Pipeline 使用的是StandardPipeline 类型,它里面的Value 保存在first 属性中, Value 是链式结构,可以通过getNext 方法依次获取每个Value, BaseValue 单独保存在basic 属性中( basic不可以为空,在调用addValve 方法添加Value 时basic 会同时保存到自rst 的最后一个,如果没调用addValve 方法则first 可能为空)。StandardPipeline 继承向LifecycleBase,所以实际处理生命周期的方法是startlnternal 、stoplnternal 和destroyInternal ,代码如下:

    @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);
    }
@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();
        }
    }
@Override
    protected void destroyInternal() {
        Valve[] valves = getValves();
        for (Valve valve : valves) {
            removeValve(valve);
        }
    }

  startlnternal 方法和stopInternal 方法处理的过程非常相似,都是使用临时变量current 来遍历Value 链里的所有Value ,如果first 为空则使用basic ,然后遍历所有Value 并调用相应的start 和stop 方法,然后设置相应的生命周期状态。destroyInternal 方法是删除所有Value。
  Pipeline 管道处理请求的实现方法
  Pipeline 调用所包含Value 的invoke 方法来处理请求,并且在BaseValue 里又调用了子容器Pipeline 所包含Value 的invoke 方法,直到最后调用了Wrapper 的Pipeline 所包含的BaseValue ——StandardWrapperValve 。
  Connector 在接收到请求后会调用最顶层容器的Pipeline 来处理,顶层容器的Pipeline 处理完之后就会在其BaseValue 里调用下一层容器的Pipeline 进行处理.这样就可以逐层调用所有容器的Pipeline 来处理了。Engine 的BaseValue 是StandardEngineValve ,它的invoke 代码如下:

@Override
    public final void invoke(Request request, Response response)
        throws IOException, ServletException {

        // Select the Host to be used for this Request
        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());
        }

        // Ask this Host to process this request
        host.getPipeline().getFirst().invoke(request, response);

    }

  这里的实现非常简单,首先从request 中获取到Host ,然后调用其管道的第一个Value的invoke 方法进行处理。Host 的BaseValue 也同样会调用Context 的Pipeline, Context 的Base Value 会调用Wrapper 的Pipeline, Wrapper 的Pipeline 最后会在其BaseValue ( StandardWrapper Valve )中创建FilterChain J-f:调用其doFilter 方法来处理请求, FilterChain 包含着我们配置的与请求相匹配的Filter 和Servlet ,其doFilter 方法会依次调用所有Filter 的doFilter 方法和Servlet 的service 方法,这样请求就得到处理了。
  Filter 和Serviet 实际处理请求的方法在Wrapper 的管道Pipeline 的BaseValue—-StandardWrapperValve 中调用,生命周期相关的方法是在Wrapper 的实现类StandardWrapper 中调用。

猜你喜欢

转载自blog.csdn.net/gchd19921992/article/details/79076355