第11章——StandardWrapper

来源:互联网 发布:数据融合 技术指标 编辑:程序博客网 时间:2024/06/01 09:53

第十一章 StandardWrapper

11.1 方法调用序列

1.调用和连接器关联的容器的invoke()方法。
2.调用该容器的管道的invoke方法,依次会调用所有管道阀,最后调用基础阀。
3.基础阀调用相应的Wrapper实例处理HTTP请求,调用Wrapper实例中的invoke方法。
4.Wrapper容器调用其管道的invoke方法的阀,最后调用基础阀。
5.基础阀调用allocate方法获取servlet实例。
6.allocate方法调用load方法载入相应的servlet类。
7.load方法调用servlet实例的init方法、service方法。

11.2 servlet类载入的关键——SingleThreadModel

如果servlet类是想了javax.servlet.SingleThreadModel接口,这个的servlet类也称为SingleThreadModel(STM)servlet类。根据Servlet规范,实现此接口的目的是保证servlet实例一次只能处理一个请求。但是该接口不能防止servlet访问共享资源造成的同步问题,在servlet2.4中已经弃用该接口,但是还是对该接口提供了支持。

11.3 StandardWrapper

我们知道StandardWrapper对象的主要任务就是载入他所代表的servlet类,并进行实例化。StandardWrapper并不调用servlet的service方法,而是再基础阀中完成调用。StandardWrapperValve对象通过allocate方法获取servlet实例。

当StandardWrapperValve获取servlet实例时,必须要考虑该类是否实现SingleThreadModel接口。
①没有实现,只载入servlet类一次,每次都返回同一个实例。
②实现,StandardWrapper实例会维护一个STM servlet实例池。

11.3.1 分配servlet实例

我们知道,基础阀通过调用StandWrapper实例的allocate方法获取servlet实例。
public javax.servlet.Servlet allocate() throws ServletException;

下面来看下对STM servlet的处理:
对于该类servlet,allocate方法试图从对象池中返回一个servlet实例。变量instancePool是一个java.util.Stack类型的栈,其中保存了所有STM servlet实例。
①只要STM servlet不超过指定的最大值,allocate方法会返回一个STM servlet实例。
②如果大于或等与最大值。则它会调用变量instancePool栈的wait方法进入等待状态,直到摸个STM servlet实例被放回栈中。

11.3.2 载入servlet类

我们知道,StandardWrapper类实现Wrapper接口的load方法,load方法调用loadServlet方法载入某个servlet类,并调用其init方法。
void javax.servlet.Servlet.init(ServletConfig arg0) throws ServletException
我们看到init方法需要一个ServletConfig类型的对象作为参数。

11.3.3 ServletConfig对象

在11.3.2中,看到init方法需要一个ServletConfig类型的对象作为参数。
其实StandardWrapper不仅实现了Wrapper接口,还是实现了javax.servlet.ServletConfig接口。
servletConfig接口有以下四个方法:
①getServletContext
②getServletName
③getInitParameter
④getInitParameterNames

11.3.4 servlet容器的父子关系

Wrapper实例代表一个Servlet实例,已经是最小的一个容器了,不能再有子容器了。因此不应该调用其addChild方法。Wrapper的父容器只能是Context类型的容器。

11.5 StandardWrapperValve类

StandardWrapperValve类是StandardWrapper实例的基础阀,要完成以下操作:
1. 执行与该servlet实例关联的全部过滤器;

2. 执行servlet实例的service方法;

具体操作:
1. 调用StandardWrapper实例的allocate方法获取servlet实例;
2. 调用私有方法createFilterChain方法,创建过滤器链;
3. 调用过滤器链的doFilter方法,其中包括调用servlet实例的service方法;
4. 释放过滤器链;
5. 调用servlet实例的deallocate方法;
6. 若该servlet类再也不会被使用到,则调用Wrapper实例的unload方法。


tomcat过滤器…

0 0
原创粉丝点击