DispatcherServlet #doDispatch 方法大致分析
- 本篇对 SpringMVC DispatcherServlet 中 doDispatch 方法做大致的分析,不会探讨细节,目的是让读者和作者自身对 SpringMVC 的工作流程有一个宏观的了解 , 在之后的文章中会对 SpringMVC 的各个内置组件,比如 : HandlerMapping (处理器映射器) , HandlerAdapter (处理器适配器) , ViewResolver (视图解析器) , HandlerExceptionResolver (异常解析器) , 以及在文档中并不突出的 HandlerMethodArgumentResolver (参数解析器 ), HandlerMethodReturnValueHandler (返回值处理器) 等做详细说明。 —— ps : 如发现描述不正确或含糊不清的内容欢迎指正 :)
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
// 获取一个异步管理器实例(Servlet 3.0 之后才支持异步)
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
// 检查该请求的 content-Type 是否为 multipart , 如果是会将 request 对象进行包装
// 返回一个包装过的 request 对象
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
// 获取到本次请求的执行器链条(HandlerExecutionChain ),其中包括
// org.springframework.web.method.HandlerMethod 对象和对应本次请求的拦截器链
// HandlerExecutionChain 是通过 org.springframework.web.servlet.HandlerMapping
// 获取到的。由于本篇只是对 doDispatch 方法的大致了解所以不做详细说明
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
// 没有发现处理本次请求的处理器 , 将会向客户端响应 404
noHandlerFound(processedRequest, response);
return;
}
// 根据之前获取到的 HandlerMethod 对象 获取到 HandlerAdapter(处理器适配器)
// 会从多个 HandlerAdapter 中判断哪一个适合处理本次请求
// 将本次请求的处理适配到用户自定义的 Controller
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
// 执行拦截器中的 preHandle 方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 真正调用处理器
// 由之前获取到的 HandlerAdapter 进行请求的处理
// 反射调用 controller 中的处理本次请求的方法
// 返回一个 ModelAndView 实例
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 判断本次请求是否是异步处理
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
// 如果用户没有指定逻辑视图名称会设置一个默认的逻辑视图名
applyDefaultViewName(processedRequest, mv);
// 请求处理后执行拦截器中的 postHandle 方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
// As of 4.3, we're processing Errors thrown from handler methods as well,
// making them available for @ExceptionHandler methods and other scenarios.
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
// 处理本次请求结果
// 进行异常处理
// 视图渲染
// 调用拦截器中的 afterCompletion 方法
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
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);
}
}
}
}
SpringMVC WorkFlow
![SpringMVC WorkFlow 输入图片说明](https://i-blog.csdnimg.cn/blog_migrate/5b97a0382bdfc308fc524575cc7dd2fe.png)