How Tomcat Works学习笔记<五>

来源:互联网 发布:淘宝网火车票 编辑:程序博客网 时间:2024/03/28 16:54
 

Servlet容器

         Container容器是用来处理Servlet请求,并构造向web客户端发送的响应信息的模块。容器用org.apache.catalina.Container接口来表示,主要有Engine、Host、Context和Wrapper四种类型,这里先介绍Context和Wrapper。

Container接口

         一个容器container必须实现org.apache.catalina.Container接口,         在连接器那一章中使用的一样通过连接器的setContainer把容器实例传过去,然后连接器就可以调用容器的invoke方法如下:

HttpConnector connector = new HttpConnector();

    SimpleContainer container = new SimpleContainer();

connector.setContainer(container);

    每一种容器都代表不同的概念级别:

1、 Engine:代表整个catalina servlet引擎

2、  Hoset:代表虚拟主机

3、  Context:代表一个应用

4、  Wrapper:代表一个独立的servlet

每一个级别都在org.apache.catalina包下有对应接口来表示,分别是Engine、Host、Context和Wrapper,同时都有标准的实现类StandardEngine、StandardHost、StandardContext和StandardWrapper,具体见类图:

一个Engine可以包含多个Host,一个Host可以包含多个Context,一个Context可以包含一个或多个Wrapper,Wrapper没有子容器,

在容器中可以通过addChild添加子容器:

    public void addChild(Container child);

通过removeChild方法可以删除一个子容器:

    public void removeChild(Container child);

通过findChild和findChildren可以查询子容器:

public Container findChild(String name);

    public Container[] findChildren();

管道任务(Pipeline tasks)

    管道包含Container将会调用的任务,而任务是通过value来说明的,在管道中有一个基础任务,同时你可以为其添加多个任务,动态添加任务是通过修改server.xml来实现的。Task和value的实现原理类似于filter,task相当于filter chain,每个value就相当于一个filter,就像filter一样,value也可以操纵request和response对象,一个value处理完了以后就会调用下一个value,basic value总是会被最后调用。

    每一个container都包含一个Pipeline,一旦connector调用container的invoke方法以后,container都会交给它的pipeline来处理,Pipeline会调用它的第一个value,然后调用下一个value直到Pipeline中没有value为止,Container的invoke方法签名如下:

      public void invoke(Request request, Response response)

        throws IOException, ServletException;

在ContainerBase中有其的实现:

    public void invoke(Request request, Response response)

        throws IOException, ServletException {

        pipeline.invoke(request, response);

    }

每个Pipeline都有一个内部类实现ValueContext接口,在Pipeline中有一个ValueContext实例,一旦Pipeline的invoke被调用它首先会去调用ValueContext的invokeNext方法:

    public void invokeNext(Request request, Response response)

            throws IOException, ServletException ;

在其中又会去调用Value的invoke方法:

        public void invoke(Request request, Response response,

                       ValveContext context)

        throws IOException, ServletException;

从中方法中可以看到,ValueContext会把自己传进去,这样Value就可以接着调用下一个Value直到调用Base vale的invoke方法为止。

Pipeline接口

         管道接口Pipeline除了有上面提到的invoke方法以外,还有添加和删除value的addValue和removeValue方法,设置或获取basic value的setBasic或getBasic方法,basic value的职责就是处理request和相应的response对象,Pipeline接口定义如下:

         package org.apache.catalina;

import java.io.IOException;

import javax.servlet.ServletException;

         public interface Pipeline {

                   public Valve getBasic();

                   public void setBasic(Valv e valve);

                   public void addValve(Valve valve);

                   public Valve[] getValves();

                   public void invoke(Request request, Response response)

             throws IOException, ServletException;

                   public void removeValve(Valve valve);

}

Value接口

         Value是用来处理request的,除了invoke方法外,还有getInfo方法获取Value的一些描述信息:

    package org.apache.catalina;

import java.io.IOException;

    import javax.servlet.ServletException;

    public interface Valve {

        public String getInfo();

       public void invoke(Request request, Response response,

ValveContext context)throws IOException, ServletException;

}

ValueContext接口

    ValueContext处理invokeNext方法外,也有一个getInfo方法,接口定义如下:

    package org.apache.catalina;

import java.io.IOException;

import javax.servlet.ServletException;

public interface ValveContext {

    public String getInfo();

public void invokeNext(Request request, Response response)throws IOException, ServletException;

}

Contained接口

         每个Value都可以选择性的实现org.apache.catalina.Contained接口,表示该Value至少分配给一个Container。

         public interface Contained {

        public Container getContainer();

        public void setContainer(Container container);

}

Wrapper接口

Wrapper是Tomcat中的一种容器类型,该类型不能在添加子容器,用org.apache.catalina.Wrapper接口表示,用来管理servlet的生命周期。主要有两个方法allocate和load,allocate方法用来定位和初始化servlet的地址,load用来加载servlet,方法声明如下:

public Servlet allocate() throws ServletException;

    public void load() throws ServletException;

并提供了Wrapper的标准实现类StandardWrapper

Context接口

    Context代表一个web应用,可以包含一个或多个Wrapper,其中包含两个重要的方法:addWrapper和createWrapper。