Servlet 容器是用来处理请求 servlet 资源,并为 Web 客户端填充 response 对象的模块。servlet 容器是org.apache.catalina.Container 接口的实例。在 Tomcat 中,共有4中类型的容器:Engine、Host、Context和Wrapper。 Container接口 Tomcat 中的 servlet 容器必须要实现 org.apache.catalina.Container 接口。对于 Catalina 中的 servlet 容器,首先需要注意的是,共有4种类型的容器,分别对应不同的概念层次: Engine:表示整个 Catalina servlet 引擎 上述的每个概念层次都由 org.apache.catalina 包内的一个接口表示,这些接口分别是 Engine、Host、Context 和 Wrapper,它们都继承自 Container 接口。这4个接口的标准实现分别是 StandardEngine 类、StandardHos t类、StandardContext 类和 StandardWrapper 类,它们都在 org.apache.catalina.core 包内。 管道任务 管道包含 Servlet 容器将要调用的任务,一个阀表示一个具体的执行任务。管道就像是过滤器链,而阀就像是过滤器。阀与过滤器类似,可以处理传递给它的 request 对象和 response 对象。当一个阀执行完成后,会调用下一个阀继续执行。基础阀总会是最后一个执行的。 当调用了容器的 invoke() 方法后,容器会将处理工作交由管道完成,而管道会调用其中的第1个阀开始处理。当第1个阀处理完成后,它会调用后续的阀继续执行任务,直到管道中所有的阀都处理完成。 // invoke each value added to the pipeline for(int n = 0; n < values.length; n++) { values[n].invoke( ... ); } // then, invoke the basic value basicValue.invoke( ... ); Tomcat 通过引入接口 org.apache.catalina.ValueContext 来实现阀的遍历执行。当连接器调用容器的 invoke() 方法后,容器中要执行的任务并没有硬编码写在 invoke() 方法中。相反容器会调用其管道的 invoke() 方法。 public void invoke(Request request, Response response) throws IOException, ServletException { pipeline.invoke(request, response); } 管道必须保证添加到其中的所有阀及其基本阀都被调用一次,这是通过创建个 ValueContext 接口实例来实现的。创建 ValueContext 实例后,管道会调用 ValueXOntext 实例的 invokeNext() 方法。 public void invoke(Request request, Response response, ValueContext valueContext) throws IOException, ServletException { // Pass the request and response on to the next value in our pipeline valueContext.invokeNext(request, response); // now perform what this value is supposed to do // ... } org.apache.catalina.core.StandarPipeline 类是所有 Servlet 容器中的 Pipeline 接口的实现。 protected class StandardPipelineValueContext implements ValueContext { protected int stage = 0; public String getInfo() { return info; } public void invokeNext(Request request, Response response) throws IOException, ServletException { int subscript = stage; stage = stage + 1; // Invoke the requested Value for the current request thread if(subscript < values.length) { values[subscript].invoke[request, response , this); } else if((subscript == values.length) && (basic != null)) { basic.invoke(request, response, this); } else { throw new ServletException(sm.getString("standardPipeline.noValue")); } } } Tomcat5 从 StandardPipeline 类中移除了 StandardPipelineValueContext 类,使用 org.apache.catalina.core.StandardValueContext 类来调用阀。 public final class StandardValueContext implements ValueContext { protected static String Manager sm = StringManager.getmanager(Constants.Package); protected String info = "org.apache.catalina.core.StandardValueContext/1.0"; protected int stage = 0; protected Value basic = null; protected Value values[] = null; public String getInfo() { return info; } public final void invokeNext(Request request, Response response) throws IOException, ServletException { int subscript = stage; stage = stage + 1; // Invoke the requested Value for the current request thread if(subscript < values.length) { values[subscript].invoke[request, response , this); } else if((subscript == values.length) && (basic != null)) { basic.invoke(request, response, this); } else { throw new ServletException(sm.getString("standardPipeline.noValue")); } } void set(Value basic, Values values[]) { stage = 0; this.basic = basic; this.values = values; } } Pipeline 接口 public interface Pipeline { public Value getBasic; public void setBasic(Value value); public void addValue(Value value); public Value[] getValuse(); public void invoke(Request request, Response response) throws IOException, ServletException; public void removeValue(Value value); } Value 接口 public interface Value { public String getInfo(); public void invoke(Request request, Response response, ValueContext context) throws IOException, ServletException; } ValueContext 接口 public interface ValueContext { public String getInfo(); public void invokeNext(Request request, Response response) throws IOException, ServletException; } Contained 接口 public interface Contained { public Container getContainer(); public void setContainer(Container container); } Wrapper 接口 Wrapper级的Servlet容器是一个org.apache.catalina.Wrapper接口的实例,表示一个独立的servlet定义。Wrapper 接口继承自 Container 接口,又添加了一些额外的方法。Wrapper 接口的实现类要负责管理其基础 Servlet 类的 Servlet 生命周期,即调用 Servlet 的 init()、service()、destroy() 等方法。由于 Wrapper 已经是最低级的 Servelt 容器,因此不能再向其添加子容器。若是 Wrapper 的 addChild() 方法被调用,则抛出 IllegalArgumantException 异常。 转载请并标注: “本文转载自 linkedkeeper.com ” ©著作权归作者所有 |