您的位置:首页 > 编程语言 > Java开发

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐