现在的位置: 首页 > 综合 > 正文

How Tomcat Works 5

2018年05月22日 ⁄ 综合 ⁄ 共 3199字 ⁄ 字号 评论关闭

本章讲述Container,它的作用是处理request和response对象。本章讲述org.apache.catalina.Container接口,四种container:Engine, Host, Context, and Wrapper中的两种Context和Wrapper,其余两种在13章讲
。此前会先说说pipelining机制。

 

一,Container接口

    每个Connector都要有一个Container:

        HttpConnector connector = new HttpConnector();

        SimpleContainer container = new SimpleContainer();

        connector.setContainer(container);

 

    说一下四种Container的作用:

  •  Engine. Represents the entire Catalina servlet engine.
  •  Host. Represents a virtual host with a number of contexts.
  •  Context. Represents a web application. A context contains one or more wrappers.
  •  Wrapper. Represents an individual servlet.

    这四种类型的Container都有它们各自的接口,又都实现了Container接口,在org.apache.catalina下。它们都有各自的实现类,一般都以Standard开头,都继承于ContainerBase类,在org.apache.catalina.core包下。

 

    一个可以正常运转的服务器实际上并不需要全部这四种Container。

    Container是有层次关系的,每个container都可以有0到多个孩子container,可以通过

        public void addChild(Container child);

        public void removeChild(Container child);

        public Container findChild(String name);

        public Container[] findChildren();

    等方法处理。

 

    Container里可以包含很多其它组件Loader, Logger, Manager, Realm, and Resources,所以接口中有这些组件的set get方法。

    Container被设计成admin可以在部署时随意安排它执行哪些操作,这是通过编辑server.xml做到的,而具体是通过pipeline的机制实现的。

 

二,pipeline机制

pipeline机制很像Filter机制,pipeline就像filter chain,而valve就像filter。像Filter 一样,pipeline可以处理通过它的request和response对象,从第一个valve开始,当某个valve处理完,就传给pipeline中的下一个valve,直到最后一个basic valve被调用。可以想象代码可能会类似这样:

// invoke each valve added to the pipeline
for (int n=0; n<valves.length; n++) {

valve[n].invoke( ... );

}

// then, invoke the basic valve

basicValve.invoke( ... );

 

但是在这里,Tomcat没有用这种方法,而是用了org.apache.catalina.ValveContext接口,说实话,现在也没明白这样有什么好

首先在connector调用container的invoke方法时,container会简单的调用pipeline的invoke方法:

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

pipeline.invoke(request, response);

}

pipeline里有个inner class叫StandardPipelineValveContext,实现了ValveContext接口,此接口中有个方法:

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 (sm.getString("standardPipeline.noValve"));

}

}

具体的不多说了,一看便知,主要是先把valve走一遍,最后搞basic valve。

tomcat 5和这有点区别,把ValveContext的实现类单搞出来了,而不再是inner class。

除了pipeline,valve,valvecontext接口外,还有个Contained接口,主要是把valve和container联系起来。

 

三, Wrapper, Context接口

它们的实现类会分别在11、12章讲解。

wrapper是最小的context,它只负责一个特定的servlet的init,service,destroy等生命周期。有两个重要方法:allocate和load。

其中load负责载入和初始化servlet,也就是用classloader装载类,然后调用它的init方法。而allocate负责分配这个已经初始化的servlet,其中会检查servlet是否实现javax.servlet.SingleThreadModel接口,关于此会在11章详解

 

四,Application

第一个只用wrapper的例子没什么说的,除了load那部分可以看看。

第二个例子关于context,使用了mapper,但在tomcat 5中已经不用了
。因为用context时,需要知道请求的是哪个servlet,也就是要知道用哪个wrapper负责处理,所以在最初,把uri请求和对应的wrapper名字对儿放到了一个hashmap里,在请求来的时候,再从这个map里找。起用有个接口叫Mapper,里面有5个方法:

public Container getContainer();

public void setContainer(Container container);

public String getProtocol();

public void setProtocol(String protocol);

public Container map(Request request, boolean update);

这里面getProtocol,setProtocol是为了context可以用不同的mapper处理不同的协议,比如http协议和https协议可以用两个不同的mapper处理。而map方法则是返回要处理请求的wrapper的。

【上篇】
【下篇】

抱歉!评论已关闭.