天天看点

深入理解Tomcat系列之五:Context容器和Wrapper容器

前言

context容器是一个web项目的代表,主要管理servlet实例,在tomcat中servlet实例是以wrapper出现的,现在问题是如何才能通过context容器找到具体的servlet呢?在解决这个问题之前,context容器需要先启动,启动的过程就是加载个类资源文件以及打开子容器以及pipeline管道的过程。启动context容器后,就可以处理具体的请求了,具体是通过request对象,从代码清单4-3的<code>wrapper wrapper = request.getwrapper()</code>就可以看出来。

那么context调用invoke方法后又发生什么了呢?具体执行的是org.apache.catalina.core.standardcontextvalve的invoke方法。相当于进入了context管道中,要开始通过管道中一个个闸门了。

standardcontext的处理流程可以用下面的图简化:

深入理解Tomcat系列之五:Context容器和Wrapper容器

代码清单4-3:

禁止直接访问web-inf或者meta-inf目录下的资源

选择具体的wrapper处理请求

返回一个确认响应

调用wrapper容器的invoke方法,把处理请求交给standardwrappervalve处理

wrapper容器

wrapper容器负责管理一个servlet,包括servlet的装载、初始化、资源回收。wrapper是最底层的容器,其不能在添加子容器了。wrapper是一个接口,其标准实现类是standardwrapper,下面是这两个类的结构:

深入理解Tomcat系列之五:Context容器和Wrapper容器
深入理解Tomcat系列之五:Context容器和Wrapper容器

上面的图都只是类的一部分,由于wrapper与servlet息息相关,其中的loadservlet方法负责装载servlet,其源码如下:

代码清单4-4:

该类主要负责初始化一个servlet实例,并调用该实例的init方法,然后通知感兴趣的事件监听程序。代码清单4-3中调用了wrapper的invoke方法,这个方法完成什么呢?

代码清单4-5:

初始化一些本地变量

判断当前应用是否可用,就是判断是否确实有这个项目

分配一个servlet实例

为请求创建一个过滤器链

过滤器过滤请求

关闭过滤器

重新委派原来委派的servlet实例

释放资源

这个方法与上面的loadservlet关系如下:

深入理解Tomcat系列之五:Context容器和Wrapper容器

可以看出在调用loadservlet的allocate方法的时候调用了standardwrappervalve的invoke方法,在wrapper容器获得请求后,通过allocate方法从实例池栈中弹出一个servlet实例来处理这个请求,servlet实例被封装成filterchain对象,紧接着通过一系列的过滤器过滤到达servlet.service()方法。这个过程可以如下:

深入理解Tomcat系列之五:Context容器和Wrapper容器

继续阅读