Tomcat源码系列:
- Tomcat初始化源码流程分析(图解及源码注释) (一)
- Tomcat初始化源码流程分析(图解及源码注释) (二)
- Tomcat启动源码流程分析(图解及源码注释) (三)
- Tomcat启动源码流程分析(图解及源码注释) (四)
- Tomcat请求源码流程分析(图解及源码注释) (五)
- Tomcat请求源码流程分析(图解及源码注释) (六)
本章为Tomcat请求解析流程的第二章,主要内容为在请求转交给Coyote适配器后的流程分析
紧接上文中请求交由Processor处理.
Tomcat初始化源码不适用于新手
文章内容只有部分流程的源码分析,通过代码注释的方法,仅适用于Tomcat的源码有一定的了解的同学.
目录
1.AbstractProcessorLight.process()
3.1 StandardEngineValve.invoke()
3.2 StandardHostValve.invoke()
3.3 StandardContextValve.invoke()
3.4 StandardWrapperValve.invoke()
4.wrapper.allocate() 构造Servlet实例
5. filterChain.doFilter(request.getRequest(),response.getResponse())
5.1 internalDoFilter(request,response);
5.2 servlet.service(request, response);
1.AbstractProcessorLight.process()
当请求由Endpoint交由Processor处理时,首先经过的就是AbstractProcessorLight.process()
public SocketState process(SocketWrapperBase<?> socketWrapper, SocketEvent status)
throws IOException {
SocketState state = SocketState.CLOSED;
Iterator<DispatchType> dispatches = null;
do {
if (dispatches != null) {
DispatchType nextDispatch = dispatches.next();
if (getLog().isDebugEnabled()) {
getLog().debug("Processing dispatch type: [" + nextDispatch + "]");
}
state = dispatch(nextDispatch.getSocketStatus());
if (!dispatches.hasNext()) {
state = checkForPipelinedData(state, socketWrapper);
}
} else if (status == SocketEvent.DISCONNECT) {
} else if (isAsync() || isUpgrade() || state == SocketState.ASYNC_END) {
state = dispatch(status);
state = checkForPipelinedData(state, socketWrapper);
} else if (status == SocketEvent.OPEN_WRITE) {
// Extra write event likely after async, ignore
state = SocketState.LONG;
} else if (status == SocketEvent.OPEN_READ) {
//调度Http11Processor.service方法
state = service(socketWrapper);
} else if (status == SocketEvent.CONNECT_FAIL) {
logAccess(socketWrapper);
} else {
state = SocketState.CLOSED;
}
....
}
} while (state == SocketState.ASYNC_END ||
dispatches != null && state != SocketState.CLOSED);
return state;
}
2. CoyoteAdapter.service()
此时在service方法中会调用CoyoteAdapter.service(),至此请求就即将被发送给Engine引擎.
//获取Coyote适配器,并调用其service方法
getAdapter().service(request, response);
3. Valve.inkove()
3.1 StandardEngineValve.invoke()
在Coyote适配器中,会获取Engine容器的第一个Valve,即StandardEngineValve,并执行.
// 获取容器的第一个Valve执行
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
3.2 StandardHostValve.invoke()
接下来依次调用host,context,wrapper的valve并执行.
host.getPipeline().getFirst().invoke(request, response);
3.3 StandardContextValve.invoke()
context.getPipeline().getFirst().invoke(request, response);
3.4 StandardWrapperValve.invoke()
wrapper.getPipeline().getFirst().invoke(request, response);
4.wrapper.allocate() 构造Servlet实例
当请求来到StandardWrapperValve时,首先会先实例化Servlet.
if (!unavailable) {
servlet = wrapper.allocate();
}
5. filterChain.doFilter(request.getRequest(),response.getResponse())
然后会开始构建Filter过滤器链.并执行过滤器链
//构造过滤器链
ApplicationFilterChain filterChain =
ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
try {
if ((servlet != null) && (filterChain != null)) {
// Swallow output if needed
if (context.getSwallowOutput()) {
try {
SystemLogHandler.startCapture();
if (request.isAsyncDispatching()) {
request.getAsyncContextInternal().doInternalDispatch();
} else {
//执行Filter
filterChain.doFilter(request.getRequest(),
response.getResponse());
}
} finally {
String log = SystemLogHandler.stopCapture();
if (log != null && log.length() > 0) {
context.getLogger().info(log);
}
}
} else {
if (request.isAsyncDispatching()) {
request.getAsyncContextInternal().doInternalDispatch();
} else {
filterChain.doFilter
(request.getRequest(), response.getResponse());
}
}
}
}
5.1 internalDoFilter(request,response);
当我们跟踪进doFilter方法,其中会调用internalDoFilter(request,response)方法
internalDoFilter(request,response);
5.2 servlet.service(request, response);
在这个方法中会获取到Servlet实例,并调用service方法.
servlet.service(request, response);
6.HttpServlet.service()
我们知道我们用户自定义的Servlet实际上都是继承了HttpServlet方法,那么我们跟踪到HttpServlet.service()
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException(lStrings.getString("http.non_http"));
}
service(request, response);
}
7.正式执行自定义Servlet.
在转换完Response和Request后,service会调用重载的service方法,此时则开始正式执行Get,Post等等.
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
} catch (IllegalArgumentException iae) {
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);
} else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
//
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
至此Tomcat请求过程就正式结束了.