Spring MVC 核心调用流程

概述 :
 
DispatcherServlet作为Spring MVC的核心控制器 , 初始化组件 , 处理客户端发送的请求 , 并返回 ModelAndView , 进行视图渲染 。主要是实现了父类 FrameworkServlet的抽象方法 doService() 。
 
DispatcherServlet 类图

Spring MVC 核心调用流程

文章插图
 
DispatcherServlet的 initStrategies方法如何被调用的
入口类:AbstractApplicationContext # refresh
├─ refresh
│├─ finishRefresh
││└─ publishEvent
│││├─ publishEvent
│││└─ multicastEvent
││││└─ invokeListener
│││││└─ doInvokeListener
││││││└─ onApplicationEvent
│││││││└─ onRefresh
││││││││└─ onRefresh
│││││││││└─ initStrategies
进入 onRefresh方法
所在类:org.springframework.web.servlet. DispatcherServlet
protected void onRefresh(ApplicationContext context) {initStrategies(context);}protected void initStrategies(ApplicationContext context) {// 初始化文件上传处理initMultipartResolver(context);// 初始化本地化 ResolverinitLocaleResolver(context);// 初始化主题 ResolverinitThemeResolver(context);// 初始化 URL映射关系initHandlerMappings(context);// 初始化Handler接口适配器initHandlerAdapters(context);// 初始化异常处理的 handlerinitHandlerExceptionResolvers(context);// 初始化请求路径转换initRequestToViewNameTranslator(context);// 初始化视图解析initViewResolvers(context);// 初始化 flashmap管理initFlashMapManager(context);}::: warning 知识点 initStrategies方法中的所有初始化组件中之所以可以拿到值 , 主要是通过 @EnableWebMvc注解 , 调用到 WebMvcConfigurationSupport类中的各个 @Bean注解的方法 , 完成的实例化过程 。:::
请求调用流程当父子容器都启动完成后 , 开始进行请求的响应处理 , 
  • 请求 http://localhost:9090/user/queryUser地址
进入 service方法
所在类:JAVAx.servlet.http. HttpServlet
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String method = req.getMethod();long lastModified;if (method.equals("GET")) {lastModified = this.getLastModified(req);if (lastModified == -1L) {this.doGet(req, resp);}// ...... 省略}
进入 doGet方法
所在类:org.springframework.web.servlet. FrameworkServlet
@Overrideprotected final void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {processRequest(request, response);}
进入 processRequest方法
所在类:org.springframework.web.servlet. FrameworkServlet
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {long startTime = System.currentTimeMillis();Throwable failureCause = null;doService(request, response);}
进入 doService方法
所在类:org.springframework.web.servlet. DispatcherServlet
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {logRequest(request);try {// 调用核心流程doDispatch(request, response);}finally {if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {// Restore the original attribute snapshot, in case of an include.if (attributesSnapshot != null) {restoreAttributesAfterInclude(request, attributesSnapshot);}}}}请求调用 核心入口
请求最终进入 doDispatch方法
所在类:org.springframework.web.servlet. DispatcherServlet
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;boolean multipartRequestParsed = false;// 异步管理WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);try {ModelAndView mv = null;Exception dispatchException = null;try {// 文件上传解析 , 如果请求类型是multipart将通过// MultipartResolver进行文件上传解析processedRequest = checkMultipart(request);multipartRequestParsed = (processedRequest != request);// 对当前请求匹配一个合适的 handler , 重要方法mappedHandler = getHandler(processedRequest);if (mappedHandler == null) {noHandlerFound(processedRequest, response);return;}// 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 (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}}if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}applyDefaultViewName(processedRequest, mv);mappedHandler.applyPostHandle(processedRequest, response, mv);}catch (Exception ex) {dispatchException = ex;}catch (Throwable err) {dispatchException = new NestedServletException("Handler dispatch failed", err);}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 afterCompletionif (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}else {// 如果是multipart的请求 , 清空上传的multipart资源if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}}


推荐阅读