SpringMVC 源码学习 —— DispatcherServlet #doDispatch 方法大致分析
2017-06-10 00:00
816 查看
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: &quo 3ff0 t; + 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
相关文章推荐
- 6、SpringMVC源码分析(1):分析DispatcherServlet.doDispatch方法,了解总体流程
- SpringMVC源码分析(1):分析DispatcherServlet.doDispatch方法,了解总体流程
- SpringMVC之请求处理源码分析从service到doDispatch之doDispatch分析(二)
- SpringMVC源码分析--容器初始化(五)DispatcherServlet
- springMVC源码分析--容器初始化(二)DispatcherServlet
- SpringMVC源码分析--容器初始化(五)DispatcherServlet
- SpringMVC源码分析--容器初始化(五)DispatcherServlet
- SpringMVC之请求处理源码分析从service到doDispatch(一)
- SpringMVC源码分析--容器初始化(五)DispatcherServlet
- springMvc源码学习之:利用springMVC随时随地获取HttpServletRequest等对象
- 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]
- jQuery源码研究分析学习笔记-jQuery原型属性和方法(九)
- springmvc 学习笔记--DispatcherServlet 源码分析
- SpringMVC源码分析--容器初始化(四)FrameworkServlet
- springMvc源码学习之:spirngMVC获取请求参数的方法2
- SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解
- 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析] – format丶
- java学习之旅57、58--数组_StringBuilder和StringBuffer的使用_JDK源码分析内部机制、常用方法补充_常见面试题答法
- servlet中doget dopost方法源码分析