三、spring核心doDispatch
2021-01-11
spring前期做了足够的准备工作,接下来才是真正的流程部分,这些在doDispatch(HttpServletRequest request, HttpServletResponse response) 方法中,下面我们先对这个方法做一个大致的勾勒,看看到底都做了什么工作,然后再仔细的刨析其中的方法。
1、WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); request中设置属性asyncManager 并返回asyncManager。这个管理器主要用来管理异步请求的处理。当业务逻辑复杂(或者其他原因),为了避免请求线程阻塞,需要委托给另一个线程的时候。异步场景从t1线程开始处理,在t2线程中生成结果,线程3使用和保存结果继续处理。
2、processedRequest = checkMultipart(request); 判断是否有上传文件
multipartRequestParsed = (processedRequest != request);
3、 mappedHandler = getHandler(processedRequest); //返回handler的HandlerExecutionChain ,handler的执行链其实是uri地址,以此作为key值保存在map中
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); //获取handler,并装配到adpter适配器中
// Process last-modified header, if supported by the handler.
4、 String method = request.getMethod(); //get方法判断
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
} //处理前置方法
5、 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); //通过适配器处理得到结果modelAndView.
6、
if (asyncManager.isConcurrentHandlingStarted()) {
return;
} //如果异步处理则返回
applyDefaultViewName(processedRequest, mv); //查找是否有默认视图名称,不存在设置默认视图名
mappedHandler.applyPostHandle(processedRequest, response, mv); //后置方法处理
7、processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); //processDispatchResult 总共做了四步,首先判断异常、其次返回结果,然后判断异步,最后完成后触发收尾工作----mappedHandler.triggerAfterCompletion(request, response, null)。
8、异步处理,以及上传清空
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}