|
从前看过关于Tomcat的书,但是很快就忘记了。这次又看了一遍,随手画了个草图,来帮助记忆,没办法,我这个人,看图记忆有效些。
Tomcat里有容器(Container)这么个概念,还有连接器(Connector)。我这幅图只画了容器这块儿的。
总共有四种类型的容器:engine,host,context和wrapper。一个context里一般有一个或者多个wrapper,每个wrapper都对应了一个servlet。容器内所有组件的生命周期都由容器负责;容器内所有组件的行为都能受到容器的监控;容器可以对进出容器内部的数据进行改动。这是我能想到的采用容器的好处。
如上图所示,图片中象梯子一样的那部分,我想用它代表容器的Pipeline。Host有自己的Pipeline,Context也有自己的Pipeline。一格一格的表示这个Pipeline里有很多Valve。Valve用来控制进入Host内部的数据。
在最靠近Host内部的一个Valve,也就是数据进入Host要通过的最后一个Valve,叫做BasicValve。如果Host里有很多个Context,就是说有很多个Web程序,数据流在BasicValve里就会流向相应Context的Pipeline。
鉴于上面的内容有些浅薄,那我再进一小步吧。
我就按照上图来浅浅地描述一下request被处理的流程。
对于每一个HTTP请求,connector调用其关联的container的invoke方法,该container调用其子容器的invoke方法。具体实现是在CoyoteAdapter的service方法里,由下面这一句就进入了Container的范围了。
connector.getContainer().getPipeline().getFirst().invoke(request, response);
getContainer()返回一个Host对象,然后得到Host对象的Pipeline,在调用Pipeline中第一个Valve对象的invoke方法。在Host对象的Pipeline中的最后一个Valve是StandardHostValve。
在StandardHostValve里,invoke函数中有:
context.getPipeline().getFirst().invoke(request, response);
这句函数就开始进入Context的范围了。同样的,在Context对象的Pipeline中的最后一个Valve是StandardContextValve。
在StandardContextValve里,invoke函数中有:
wrapper.getPipeline().getFirst().invoke(request, response);
这句函数就进入Wrapper的范围了。
Wrapper是这里面最小的容器,其内部就没有其它子容器了。当执行到Wrapper对象的Pipeline中最后一个Valve(StandardWrapperValve)时,会有下面的语句:
filterChain.doFilter(request.getRequest(),
response.getResponse());
在FilterChain里,当最后一个filter被调用后,就会运行下面的语句。
servlet.service(request, response);
到这里,一个request就经历了重重考验,到了其目的地。 |
|
|