Spring MVC的执行流程图And源码浅析(挺重要的呀)

先上图:

  1. 百度里的:
    在这里插入图片描述
  2. 自己仿着画的
    在这里插入图片描述
  3. BigDevil_ 画的
    在这里插入图片描述

再上文字描述:

转载自:一页知秋否

SpringMVC的具体工作原理

1、客户端用户发送请求至前端控制器DispatcherServlet。

2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。

3、 HandlerMapping处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

4、DispatcherServlet调用HandlerAdapter处理器适配器,HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

5、Controller控制器执行完成返回ModelAndView,HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

6、 DispatcherServlet前端控制器将ModelAndView传给ViewReslover视图解析器。

7、 ViewReslover解析后返回具体View。

8、DispatcherServlet根据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 {
		ModelAndView mv = null;
		Exception dispatchException = null;

		try {
			processedRequest = checkMultipart(request);
			multipartRequestParsed = (processedRequest != request);
               

// -------------- 这是 前端控制器 请求查询 处理器 的过程 start ----------------
			// Determine handler for the current request.
            // 1、请求HandlerMapping处理器映射器查询Handler处理器
            // 返回HandlerExecutionChain处理执行链:1~n个拦截器和处理器handler
			mappedHandler = getHandler(processedRequest);
			if (mappedHandler == null || mappedHandler.getHandler() == null) {
				noHandlerFound(processedRequest, response);
				return;
			}
// -------------- 这是 前端控制器 请求查询 处理器 的过程 end ----------------
      
      
               
// -------------- 这是 前端控制器 请求执行 处理器 的过程 start ----------------
			// Determine handler adapter for the current request.
            // 2、根据处理器执行链的处理器对象获取处理器适配器
            // 先从处理器执行链HandlerExecutionChain中获取处理器对象Handler
            // 再从处理器Handler对象获取处理器适配器HandlerAdapter
			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: " + lastModified);
				}
				if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
					return;
				}
			}
			
            //--------调用preHandle-----------
            // 3、正序遍历HandlerExecutionChain的拦截器数组
            // 依次执行拦截器的preHandle方法
            // 提示:下面的mappedHandler即为HandlerExecutionChain对象
			if (!mappedHandler.applyPreHandle(processedRequest, response)) {
				return;
			}

			// Actually invoke the handler.
            // --------调用 目标方法------
         	// 4、HandlerAdapter处理器适配器调用handle方法获取ModelAndView对象
			mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

			if (asyncManager.isConcurrentHandlingStarted()) {
				return;
			}

			applyDefaultViewName(request, mv);
             // --------调用 postHandle------
             // 5、逆序遍历HandlerExecutionChain的拦截器数组
             // 依次执行拦截器的postHandle方法
             // 提示:下面的mappedHandler即为HandlerExecutionChain对象
			mappedHandler.applyPostHandle(processedRequest, response, mv);
		}
		catch (Exception ex) {
			dispatchException = ex;
		}
// -------------- 这是 前端控制器 请求执行 处理器 的过程 end ----------------
           


// -------------- 这是 前端控制器 请求解析 视图 的过程 start ----------------
        // (方法的详细内容见下面的processDispatchResult方法)
        // 6、请求视图解析器解析ModelAndView对象
        // 并调用View对象的render方法真正的实际渲染视图
		processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
// -------------- 这是 前端控制器 请求解析 视图 的过程 end ----------------
           
           
	}
	catch (Exception ex) {
		triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
	}
	catch (Error err) {
		triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
	}
	finally {
		if (asyncManager.isConcurrentHandlingStarted()) {
			// Instead of postHandle and afterCompletion
			if (mappedHandler != null) {
			 /**
			 * Apply afterConcurrentHandlerStarted callback on mapped AsyncHandlerInterceptors.
			 */
				mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
			}
		}
		else {
			// Clean up any resources used by a multipart request.
			if (multipartRequestParsed) {
				cleanupMultipart(processedRequest);
			}
		}
	}
}


// 接第6步:请求视图解析器解析视图(详细见下面的processDispatchResult方法)
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
			HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {

	boolean errorView = false;

	if (exception != null) {
		if (exception instanceof ModelAndViewDefiningException) {
			logger.debug("ModelAndViewDefiningException encountered", exception);
			mv = ((ModelAndViewDefiningException) exception).getModelAndView();
		}
		else {
			Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
			mv = processHandlerException(request, response, handler, exception);
			errorView = (mv != null);
		}
	}

	// Did the handler return a view to render?
	if (mv != null && !mv.wasCleared()) {
        // 6.1 前端控制器请求视图解析器解析ModelAndView对象(render的详细代码见下面)
        // 渲染给定的ModelAndView,这是处理请求的最后一个阶段。
        // 它可能涉及通过名称解析视图。
		render(mv, request, response);
		if (errorView) {
			WebUtils.clearErrorRequestAttributes(request);
		}
	}
	else {
		if (logger.isDebugEnabled()) {
			logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
					"': assuming HandlerAdapter completed request handling");
		}
	}

	if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
		// Concurrent handling started during a forward
		return;
	}

	if (mappedHandler != null) {
        // 6.2 逆序遍历HandlerExecutionChain的拦截器数组
        // 依次执行拦截器的afterCompletion方法
        // 提示:下面的mappedHandler即为HandlerExecutionChain对象
		mappedHandler.triggerAfterCompletion(request, response, null);
	}
}


// 接第6.1步:前端控制器请求视图解析器解析ModelAndView对象(详细代码在下面)
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
	// Determine locale for request and apply it to the response.
	Locale locale = this.localeResolver.resolveLocale(request);
	response.setLocale(locale);

	View view;
	if (mv.isReference()) {
		// We need to resolve the view name.
        // 6.1.1 通过名称解析视图
		view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
		if (view == null) {
			throw new ServletException("Could not resolve view with name '" + mv.getViewName() +
					"' in servlet with name '" + getServletName() + "'");
		}
	}
	else {
		// No need to lookup: the ModelAndView object contains the actual View object.
        // 6.1.2 获取View对象
		view = mv.getView();
		if (view == null) {
			throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +
					"View object in servlet with name '" + getServletName() + "'");
		}
	}

	// Delegate to the View object for rendering.
	if (logger.isDebugEnabled()) {
		logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");
	}
	try {
        // 6.1.3 调用View对象的render来呈现视图
        // 渲染指定模型的视图。
        // 第一步是准备请求:在JSP的情况下,这意味着将模型对象设置为请求属性。
        // 第二步是视图的实际渲染
		view.render(mv.getModelInternal(), request, response);
	}
	catch (Exception ex) {
		if (logger.isDebugEnabled()) {
			logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" +
					getServletName() + "'", ex);
		}
		throw ex;
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章