1. Http request处理时序图
2. StandardContext和StandardWrapper的构造函数:
Public StandardContext() {
super();
pipeline.setBasic(new StandardContextValve());
namingResources.setContainer(this);
}
public StandardWrapper() {
super();
pipeline.setBasic(new StandardWrapperValve());
}
3. StandardWrapper的功能
(1)加载servlet,分配servlet实例。调用service()方法留给了StandardWrapperValve【wrapperPipeline.basicValve】
(2)StandardWrapper需要知道servlet类的全限定名
(3)对于未实现SingleThreadModel的servlet, standardWrapper全局使用同一个StandardWrapper实例。对于实现了STM的servlet,standwrapper需要确保同时不能有两个线程调用一个servlet的service()方法。实际上会使用一个instancepool来为实现了STM的servlet存储实例。伪代码如下:
public class SimpleWrapperValve {
public void invoke(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// ...
Servlet instance = null; //get an instance of servlet
if(instance instanceof SingleThreadModel){
synchronized(instance) {
instance.service(request, response);
}
}else {
instance.service(request, response);
}
}
}
(4)allocate方法同样需要区分STM servlet
(5)load方法:
判断是否JSP页面【若是,加载jspWrapper】->获取classLoader->classClass.newInstance()->判断是否ContainerServlet【servlet.setWrapper(this)】->fireInstanceEvent(BEFORE_INIT_EVENT, servlet)->servlet.init(facade)->fireInstanceEvent(AFTER_INIT_EVENT,servlet)->判断是否STM【若是,入实例pool】->return Servlet实例
4. ServletConfig对象:
(1)主要方法:getServletContext(), getName(), getInitParameter(),getInitParameterNames()
5. Wrapper类
(1)调用addChild()方法抛异常
(2)可调用setParent(Context)
6. StandardWrapperFacade类
(1)需要隐藏许多StandardWrapper的内部实现,所以使用门面模式传入servlet.init()方法中。
(2)UML
7. StandardWrapperValue类
(1)主要功能:执行所有servlet相关filters, 调用servlet的service方法
(2)StandardWrapperVavle需要在invoke方法中实现:
a. 获取一个包含了使用StandardWrapper.allocate分配的servlet实例
b. 使用private createFilterChain()方法创建一个filter chain
c. 调用filter chain的doFilter()方法,也包含调用servlet.service()方法
d. 释放filter chain
e. 调用wrapper的deallocate方法
f. 如果servlet是永远不可用的,则调用wrapper的unload方法
(3)代码:
public void invoke(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//..
if(!unavailable){
servlet = wrapper.allocate();
}
// Acknowlege the request
response.sendAcknowlegement();
// Create the filter chain for the request
ApplicationFilterChain filterChain = createFilterChain(request,servlet);
filterChain.doFilter //也包含调用servlet.service方法
filterChain.release()
wrapper.deallowcate(servlet);
if(wrapper.getAvailable() == Long.MAX_VALUE){
wrapper.unload();
}
}
8. BootStrap类
public static void main(String[] args) {
System.setProperty("catalina.base",
System.getProperty("user.dir"));
Connector connector = new HttpConnector();
Wrapper wrapper1 = new StandardWrapper();
wrapper1.setName("Primitive");
wrapper1.setServletClass("PrimitiveServlet");
Wrapper wrapper2 = new StandardWrapper();
wrapper2.setName("Modern");
wrapper2.setServletClass("ModernServlet");
Context context = new StandardContext();
context.addChild(wrapper1);
context.addChild(wrapper2);
connector.setContainer(context);
connector.initialize();
connector.strart()
context.start();
}