容器

A container is a module that processes the requests for a servlet and populates the response objects for web clients 

容器是一个处理servlet请求,并为web客户端提供响应的模块。

org.apache.catalina.Container 接口定义了容器的形式,有四种容器:Engine (引擎), Host(主机), Context(上下文), 和 Wrapper(包装器)。 

容器接口 

一个容器必须实现 org.apache.catalina.Container接口。就如在第四章中看到的,传递一个Container实例给Connector对象的setContainer 方法,然后Connector对象就可以使用container的invoke方法 

  •  Engine. 表示整个Catalina的servlet引擎 

  •  Host. 表示一个拥有数个上下文的虚拟主机 

  •  Context. 表示一个Web应用,一个 context包括一个或多个wrapper 

  •  Wrapper. 表示一个独立的servlet 

一个容器可以有一个或多个低层次上的子容器。例如,一个Context有一个或多个wrapper,而wrapper 作为容器层次中的最底层,不能包含子容器。 

Pipelining Tasks(流水线任务) 

一个流水线就像一个过滤链,每一个阀门像一个过滤器。跟过滤器一样,一个阀门可以操作传递给它的request和response方法。

让一个阀门完成了处理,则进一步处理流水线中的下一个阀门,基本阀门总是在最后才被调用。 

当容器的invoke方法被调用时,它不需要知道怎么去做,把这个问题交给pipeline(调用pipeline的invoke方法),看一下他们的接口。 

//代表Valve上下文,包含一个Valve数组和baseValve。
public interface ValveContext {
    public String getInfo();
    //调用下一个Valve
    public void invokeNext(Request request, Response response)
                                throws IOException, ServletException;
}
//包含一个ValveContext
public interface Pipeline {
    public Valve getBasic();//获取base Valve
    public void setBasic(Valve valve);//设置base Valve
    public void addValve(Valve valve);//增加一个Valve
    public Valve[] getValves();//获取全部的Valve
    //container会调用该方法,把问题交给pipeline处理,pipeline在这里会调用ValveContext的invokeNext方法
    public void invoke(Request request, Response response)
                                throws IOException, ServletException;
    public void removeValve(Valve valve);//删除一个Valve
}
public interface Valve {
    public String getInfo();
    //ValveContext会调用这个方法
    public void invoke(Request request, Response response, ValveContext context)
                                throws IOException, ServletException;
}
//一个Valve类可以选择实现该接口,表明这个Valve的实现和至多一个容器绑定在了一起。
public interface Contained {
    public Container getContainer();
    public void setContainer(Container container);
}

一个container有一个pipelinecontainer的invoke方法调用pipeline的invoke方法.

//container
public void invoke(Request request, Response response)
            throws IOException, ServletException {
    pipeline.invoke(request, response);
}

pipeline的invoke方法调用container中所有valve然后调用container的basic valve的invoke方法

//pipeline
public void invoke(Request request, Response response)
    throws IOException, ServletException {
    // Invoke the first Valve in this pipeline for this request
    (new SimplePipelineValveContext()).invokeNext(request, response);
  }

protected class SimplePipelineValveContext implements ValveContext {

    protected int stage = 0;

    public void invokeNext(Request request, Response response)
      throws IOException, ServletException {
      int subscript = stage;
      stage = stage + 1;
      // Invoke the requested Valve for the current request thread
      if (subscript < valves.length) {
        valves[subscript].invoke(request, response, this);
      }
      else if ((subscript == valves.length) && (basic != null)) {
        basic.invoke(request, response, this);
      }
      else {
        throw new ServletException("No valve");
      }
    }
  } // end of inner class

在一个wrapper中, basic valve负责加载与之一对一关联的servlet类,并响应请求.

public void invoke(Request request, Response response, ValveContext valveContext)
                    throws IOException, ServletException {
    SimpleWrapper wrapper = (SimpleWrapper) getContainer();
    Servlet servlet = null;
    try {
        //加载servlet
        servlet = wrapper.allocate();
        //处理请求
        servlet.service(request.getRequest(), response.getResponse());
    } catch (ServletException e){}
}

 

posted on 2016-06-11 23:18  cbwleft  阅读(108)  评论(0)    收藏  举报