Spring MVC的请求处理流程
DispatcherServlet的处理流程图核心处理流程步骤DispatcherServlet 的初始化过程DispatcherServlet的处理流程图
核心处理流程步骤
检测是否是文件上传, 并处理根据 Request 获取 HandlerExecutionChain2-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); // 步骤1multipartRequestParsed = processedRequest != request;mappedHandler = this.getHandler(processedRequest); // 步骤2if (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)) {// 步骤3return;}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.AcceptHeaderLocaleResolver
initThemeResolver: 主题管理处理器 对应容器中的Bean是: themeResolver
从容器中获取名为themeResolver的Bean做该类型的组件, 没有则调用默认实现
默认实现: org.springframework.web.servlet.theme.FixedThemeResolver
initHandlerMappings: 处理映射器 主要做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.DefaultRequestToViewNameTranslator
initViewResolvers: 视图解析器
如果 detectAllViewResolvers = true (默认实现), 查找类型匹配机制及父Spring容器中类型为HandlerAdapter的Bean, 作为该类型组件
否则 查找名称为viewResolver的Bean, 作为该类型的组件
如果都没有找到, 则调用默认实现
默认实现: org.springframework.web.servlet.view.InternalResourceViewResolver
initFlashMapManager: 重定向数据管理器
查找名称为flashMapManager的Bean作为该类型的组件, 没有则调用默认实现
默认实现: org.springframework.web.servlet.support.SessionFlashMapManager