SpringMVC的执行流程源码分析?

it2022-05-05  92

- SpringMVC执行流程时序图, 此乃不传之秘。


- SpringMVC执行流程源码分析/源码追踪, 呕心沥血之作。

SpringMVC源码版本: 5.1.7.RELEASE

1. 源码分析: Servlet

public interface Servlet { // 初始化方法,构造方法后执行 void init(ServletConfig var1); // 每次访问servlet时候执行 void service(ServletRequest var1, ServletResponse var2); // 停止服务器时候执行 void destroy(); }

2. 源码追踪: FrameworkServlet

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpMethod httpMethod = HttpMethod.resolve(request.getMethod()); if (httpMethod != HttpMethod.PATCH && httpMethod != null) { super.service(request, response); } else { // 最终都会执行处理请求的方法 this.processRequest(request, response); } }

3. 源码追踪DispatcherServlet

protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception { this.logRequest(request); Map<String, Object> attributesSnapshot = null; if (WebUtils.isIncludeRequest(request)) { attributesSnapshot = new HashMap(); Enumeration attrNames = request.getAttributeNames(); label95: while(true) { String attrName; do { if (!attrNames.hasMoreElements()) { break label95; } attrName = (String)attrNames.nextElement(); } while(!this.cleanupAfterInclude && !attrName.startsWith("org.springframework.web.servlet")); attributesSnapshot.put(attrName, request.getAttribute(attrName)); } } request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.getWebApplicationContext()); request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver); request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver); request.setAttribute(THEME_SOURCE_ATTRIBUTE, this.getThemeSource()); if (this.flashMapManager != null) { FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response); if (inputFlashMap != null) { request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap)); } request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap()); request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager); } try { // 最终都会执行doDispatch方法 this.doDispatch(request, response); } finally { if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted() && attributesSnapshot != null) { this.restoreAttributesAfterInclude(request, attributesSnapshot); } } } 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); multipartRequestParsed = processedRequest != request; // 根据URI获取到具体的处理器方法 (三大组件之一: 处理器映射器) mappedHandler = this.getHandler(processedRequest); 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 ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) { return; } } if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // 适配器通过反射调用处理器方法 // 并返回视图和模型 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } // 如果视图是空采用默认视图 this.applyDefaultViewName(processedRequest, mv); // 拦截器处理 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); } 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); } } }

4. 追踪源码: DispatcherServlet

protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception { Locale locale = this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale(); response.setLocale(locale); String viewName = mv.getViewName(); View view; if (viewName != null) { // 根据视图解析器创建视图对象 view = this.resolveViewName(viewName, mv.getModelInternal(), locale, request); if (view == null) { throw new ServletException("Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" + this.getServletName() + "'"); } } else { view = mv.getView(); if (view == null) { throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a View object in servlet with name '" + this.getServletName() + "'"); } } if (this.logger.isTraceEnabled()) { this.logger.trace("Rendering view [" + view + "] "); } try { if (mv.getStatus() != null) { response.setStatus(mv.getStatus().value()); } // 视图渲染: AbstractView view.render(mv.getModelInternal(), request, response); } catch (Exception var8) { if (this.logger.isDebugEnabled()) { this.logger.debug("Error rendering view [" + view + "]", var8); } throw var8; } }

5. 追踪源码: AbstractView

public void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { if (this.logger.isDebugEnabled()) { this.logger.debug("View " + this.formatViewName() + ", model " + (model != null ? model : Collections.emptyMap()) + (this.staticAttributes.isEmpty() ? "" : ", static attributes " + this.staticAttributes)); } Map<String, Object> mergedModel = this.createMergedOutputModel(model, request, response); this.prepareResponse(request, response); // 合并视图与数据模型: InternalResourceView this.renderMergedOutputModel(mergedModel, this.getRequestToExpose(request), response); }

6. 追踪源码: InternalResourceView

protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { this.exposeModelAsRequestAttributes(model, request); this.exposeHelpers(request); String dispatcherPath = this.prepareForRendering(request, response); RequestDispatcher rd = this.getRequestDispatcher(request, dispatcherPath); if (rd == null) { throw new ServletException("Could not get RequestDispatcher for [" + this.getUrl() + "]: Check that the corresponding file exists within your web application archive!"); } else { if (this.useInclude(request, response)) { response.setContentType(this.getContentType()); if (this.logger.isDebugEnabled()) { this.logger.debug("Including [" + this.getUrl() + "]"); } rd.include(request, response); } else { if (this.logger.isDebugEnabled()) { this.logger.debug("Forwarding to [" + this.getUrl() + "]"); } // 转发页面 rd.forward(request, response); } } }

7. 追踪源码: RedirectView

protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws IOException { String targetUrl = this.createTargetUrl(model, request); targetUrl = this.updateTargetUrl(targetUrl, model, request, response); RequestContextUtils.saveOutputFlashMap(targetUrl, request, response); // 重定向地址 this.sendRedirect(request, response, targetUrl, this.http10Compatible); }

联系方式

QQ 569284276EM 569284276@qq.comWX 569284276点击链接加入群聊【8080实验室】: 537950751

最新回复(0)