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); } } } }