Spring MVC的请求处理流程
DispatcherServlet的处理流程图
核心处理流程步骤
- 检测是否是文件上传, 并处理
- 根据 Request 获取 HandlerExecutionChain
2-1: 首先解析 Request 的请求的Path
2-2: 根据 Path 在返回 HanlderMethod
2-3: 将 HanlderMethod + HandlerInterceptor 包装成 HandlerExecutionChain 返回. - 执行Chain的preHanlde方法
- 根据Chain的HandlerMethod, 调用对应的Controller的method, 并返回ModelAndView对象(如果ModelAndView对象为null或者没有View, 那么直接使用默认实现值返回).
- 执行Chain的postHandle方法
- 根据vm返回值渲染页面
6-1: 根据viewName解析View对象
6-2: 根据view对象渲染页面
// 从代码中解读
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
try {
ModelAndView mv = null;
Object dispatchException = null;
try {
processedRequest = this.checkMultipart(request); // 步骤1
multipartRequestParsed = processedRequest != request;
mappedHandler = this.getHandler(processedRequest); // 步骤2
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, response);
return;
}
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (this.logger.isDebugEnabled()) {
this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) { // 步骤3
return;
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 步骤4
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
this.applyDefaultViewName(processedRequest, mv); // 步骤5
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception var20) {
dispatchException = var20;
} catch (Throwable var21) {
dispatchException = new NestedServletException("Handler dispatch failed", var21);
}
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException); //步骤6
} catch (Exception var22) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
} catch (Throwable var23) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
}
} finally {
if (asyncManager.isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else if (multipartRequestParsed) {
this.cleanupMultipart(processedRequest);
}
}
}
DispatcherServlet 的初始化过程
initMultipartResolver: 文件上传处理器
从容器中获取名为multipartResolver的Bean做该类型的组件, 没有则不拥有该类型组件
默认实现: 没有默认实现initLocaleResolver: 国际化处理器
从容器中获取名为localeResolver的Bean做该类型的组件, 没有则调用默认实现
默认实现: org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolverinitThemeResolver: 主题管理处理器 对应容器中的Bean是: themeResolver
从容器中获取名为themeResolver的Bean做该类型的组件, 没有则调用默认实现
默认实现: org.springframework.web.servlet.theme.FixedThemeResolverinitHandlerMappings: 处理映射器 主要做url到处理类的映射
如果 detectAllHandlerMappings = true (默认实现), 查找类型匹配机制及父Spring容器中类型为HanlderMapping的Bean, 作为该类型组件
否则 查找名称为handlerMapping的Bean, 作为该类型的组件
如果都没有找到, 则调用默认实现
默认实现:1. org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping() 2. org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
initHandlerAdapters: 处理适配器 处理器的真正实现
如果 detectAllHandlerAdapters = true (默认实现), 查找类型匹配机制及父Spring容器中类型为HandlerAdapter的Bean, 作为该类型组件
否则 查找名称为handlerAdapter的Bean, 作为该类型的组件
如果都没有找到, 则调用默认实现
默认实现:1. org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter 2. org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter 3. org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
initHandlerExceptionResolvers: 异常处理器
如果 detectAllHandlerExceptionResolvers = true (默认实现), 查找类型匹配机制及父Spring容器中类型为HandlerAdapter的Bean, 作为该类型组件
否则 查找名称为handlerExceptionResolver的Bean, 作为该类型的组件
如果都没有找到, 则调用默认实现
默认实现:1. org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver 2. org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver 3. org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
initRequestToViewNameTranslator: 视图名称翻译器
查找名称为viewNameTranslator的Bean作为该类型的组件, 没有则调用默认实现
默认实现: org.springframework.web.servlet.view.DefaultRequestToViewNameTranslatorinitViewResolvers: 视图解析器
如果 detectAllViewResolvers = true (默认实现), 查找类型匹配机制及父Spring容器中类型为HandlerAdapter的Bean, 作为该类型组件
否则 查找名称为viewResolver的Bean, 作为该类型的组件
如果都没有找到, 则调用默认实现
默认实现: org.springframework.web.servlet.view.InternalResourceViewResolverinitFlashMapManager: 重定向数据管理器
查找名称为flashMapManager的Bean作为该类型的组件, 没有则调用默认实现
默认实现: org.springframework.web.servlet.support.SessionFlashMapManager
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 zhao4xi@126.com
文章标题:Spring MVC的请求处理流程
文章字数:990
本文作者:Zhaoxi
发布时间:2018-12-27, 15:11:12
最后更新:2019-09-21, 15:12:21
原始链接:http://zhao4xi.github.io/2018/12/27/Spring-MVC的请求处理流程/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。