SpringMVC系列(一)执行流程

和自甴很熟 提交于 2020-01-13 18:03:07

本系列结合源码(基于springboot2.1.4),分析springmvc的执行流程。

先上一个完整的流程图,借用网络上的:
在这里插入图片描述

我们知道,前端发起的请求首先到tomcat,最终执行的是servlet,springmvc实现了一个servlet,叫做DispatcherServlet,其继承关系如下:
在这里插入图片描述
假设发起一个get请求,这时,servlet中的doGet方法会执行,最终执行到DispatcherServlet,链路如下:
FrameworkServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 --》FrameworkServlet#processRequest(HttpServletRequest request, HttpServletResponse response)
  --》DispatcherServlet#doService(HttpServletRequest request, HttpServletResponse response)
    --》DispatcherServlet#doDispatch(HttpServletRequest request, HttpServletResponse response)

最终进入DispatcherServlet类的doDispatch方法中。

doDispatch()方法

这个方法是sprngmvc的核心方法,所有扭转乾坤的逻辑都在这里:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
	HttpServletRequest processedRequest = request;
	//处理器执行链,包含拦截器和具体的controller
	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);

			// Determine handler for the current request.
			//确定要执行的mappedHandler,也就是要执行的controller
			mappedHandler = getHandler(processedRequest);
			if (mappedHandler == null) {
				noHandlerFound(processedRequest, response);
				return;
			}
			// Determine handler adapter for the current request.
			//得到handler适配器,总共有3种
			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;
				}
			}
			//执行拦截器的preHandle方法
			if (!mappedHandler.applyPreHandle(processedRequest, response)) {
				return;
			}
			// Actually invoke the handler.
			//执行controller,得到model和view
			mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
			if (asyncManager.isConcurrentHandlingStarted()) {
				return;
			}
			//如果没有view名字,设置一个默认的名字
			applyDefaultViewName(processedRequest, mv);
			//执行拦截器的postHandle方法
			mappedHandler.applyPostHandle(processedRequest, response, mv);
		}
		catch (Exception ex) {
			dispatchException = ex;
		}
		catch (Throwable err) {
			// As of 4.3, we're processing Errors thrown from handler methods as well,
			// making them available for @ExceptionHandler methods and other scenarios.
			dispatchException = new NestedServletException("Handler dispatch failed", err);
		}
		//渲染视图,并将跳转路径设置到response中
		//然后执行拦截器的afterCompletion方法
		processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
	}
	catch (Exception ex) {
		//抛异常,也要执行拦截器的afterCompletion方法
		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 afterCompletion
			if (mappedHandler != null) {
				mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
			}
		}
		else {
			// Clean up any resources used by a multipart request.
			if (multipartRequestParsed) {
				cleanupMultipart(processedRequest);
			}
		}
	}
}

主要步骤:
1.确定handlerMapping,并从其中得到HandlerExecutionChain执行链,这个执行链包含了拦截器以及controller方法路径;
2.确定handler适配器,总共有3种:
3.利用适配器执行handler,也就是controller,但是如果有拦截器,那么要先执行拦截器相关方法。
4.渲染视图并返回

关于handlerMapping和适配器在容器中的初始化在《SpringMVC系列(二)HandlerMapping初始化》中分析。
上面是springmvc大致的请求流程,下面针对具体方法详细分析。

getHandler(HttpServletRequest request)

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
	if (this.handlerMappings != null) {
		for (HandlerMapping mapping : this.handlerMappings) {
			HandlerExecutionChain handler = mapping.getHandler(request);
			if (handler != null) {
				return handler;
			}
		}
	}
	return null;
}

方法逻辑比较简单,就是遍历
这里handlerMappings是个list,默认有5个实例对象,共4种类型:

  • SimpleUrlHandlerMapping
  • RequestMappingHandlerMapping,处理@Controller修饰的类中,@RequestMapping修饰的方法
  • BeanNameUrlHandlerMapping
  • SimpleUrlHandlerMapping,类型同第一个,但是是不同的实例对象
  • WelcomePageHandlerMapping,默认应用欢迎页面

遍历然后调用mapping.getHandler(request)方法获取HandlerExecutionChain。

其中getHandler方法是在父类AbstractHandlerMapping种实现:

public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
	Object handler = getHandlerInternal(request);
	if (handler == null) {
		handler = getDefaultHandler();
	}
	if (handler == null) {
		return null;
	}
	// Bean name or resolved handler?
	if (handler instanceof String) {
		String handlerName = (String) handler;
		handler = obtainApplicationContext().getBean(handlerName);
	}

	HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

	if (logger.isTraceEnabled()) {
		logger.trace("Mapped to " + handler);
	}
	else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {
		logger.debug("Mapped to " + executionChain.getHandler());
	}

	if (CorsUtils.isCorsRequest(request)) {
		CorsConfiguration globalConfig = this.corsConfigurationSource.getCorsConfiguration(request);
		CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
		CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
		executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
	}

	return executionChain;
}

getHandlerAdapter(Object handler)

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
	if (this.handlerAdapters != null) {
		for (HandlerAdapter adapter : this.handlerAdapters) {
			if (adapter.supports(handler)) {
				return adapter;
			}
		}
	}
	throw new ServletException("No adapter for handler [" + handler +
			"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
  • RequestMappingHandlerAdapter
  • HttpRequestHandlerAdapter
  • SimpleControllerHandlerAdapter

processDispatchResult()


private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
			@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
			@Nullable 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()) {
			render(mv, request, response);
			if (errorView) {
				WebUtils.clearErrorRequestAttributes(request);
			}
		}
		else {
			if (logger.isTraceEnabled()) {
				logger.trace("No view rendering, null ModelAndView returned.");
			}
		}

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

		if (mappedHandler != null) {
			mappedHandler.triggerAfterCompletion(request, response, null);
		}
	}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!