上一篇文章主要分析了http消息从接收到回复的过程,这篇来分析消息是如何从connector传递到container。
1. Adapter初始化
之前分析到在Http11Processor 的process中调用adapter.service(request,response)得到response信息。
Adapter是究竟是如何设置的呢?这里要回到tomcat启动时的代码。
// org.apache.catalina.connector.Connector.initInternal()
// Initialize adapter
adapter = new CoyoteAdapter(this);
protocolHandler.setAdapter(adapter);
在收到消息后,如果池中没有空闲的processor,会调用Http11ConnectionHandler.createProcessor(),这里的proto就是启动时的protocolHandler
Http11Processor processor =
new Http11Processor(proto.getMaxHttpHeaderSize(), (JIoEndpoint)proto.endpoint);
processor.setAdapter(proto.adapter);
2. 从connector到servlet
从网络上找到了一张架构图,其中很详细的描述了消息流程。下面结合代码把流程梳理一下。
进入engine
connector.getService().getContainer().getPipeline().getFirst().invoke(request,response);
通过下面几个函数进入StandardEngineValve,调用invoke。
org.apache.catalina.core.StandardService.getContainer()
org.apache.catalina.core.ContainerBase.getPipeline()
org.apache.catalina.core.StandardPipeline.getFirst()
org.apache.catalina.core.StandardEngineValve.invoke(Requestrequest, Responseresponse)
进入host
// Select the Host to be used forthis Request
Host host =request.getHost();
// Ask this Host to process thisrequest
host.getPipeline().getFirst().invoke(request, response);
org.apache.catalina.valves.AccessLogValve.invoke(Requestrequest, Responseresponse)
org.apache.catalina.valves.ErrorReportValve.invoke(Requestrequest, Responseresponse)
org.apache.catalina.core.StandardHostValve.invoke(Requestrequest, Responseresponse)
进入context
//Select the Context to be used for this Request
Context context = request.getContext();
//Ask this Context to process this request
context.getPipeline().getFirst().invoke(request, response);
org.apache.catalina.core.StandardContextValve.invoke(Requestrequest, Responseresponse)
进入wrapper
//Select the Wrapper to be used for this Request
Wrapperwrapper = request.getWrapper();
wrapper.getPipeline().getFirst().invoke(request, response);
org.apache.catalina.core.StandardWrapperValve.invoke(Requestrequest, Responseresponse)
关联servlet
从instancePool中取出servlet,servlet= wrapper.allocate();
得到filterChain,ApplicationFilterChainfilterChain = factory.createFilterChain(request, wrapper, servlet);
关联servlet,filterChain.doFilter(request.getRequest(), response.getResponse());
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ServletRequestrequest, ServletResponseresponse)中
servlet.service(request, response);
servlet.service实际上就是基类javax.servlet.http.HttpServlet.service(HttpServletRequestreq, HttpServletResponse resp),会根据request的method调用虚函数doGet,doPost…。这就是我们制作servlet时通常需要完成的接口。
填充完response后再一步步返回给connector,发送到客户端。至此整个http请求过程就结束了。最后附上消息处理的运行栈
小结:
这几篇文章分析了Tomcat从启动到监听消息再到消息处理的整个过程,基本理顺了Tomcat的基本架构和流程。之后将分析Tomcat的设计模式。