SpringMVC工作原理和DispatcherServlet 源码

一、前沿

Spring MVC 是我们非常常用的框架,在使用的过程中,你了解它的工作原理吗?它的整个过程是怎样的?下面会从以下两个方面为大家一一介绍:

1)、SpringMVC 工作原理

2)、SpringMVC 核心类 DispatcherServlet 源码

二、SpringMVC 工作原理

先来看一张SpringMVC的工作原理图:

上述工作原理图清晰的展示了SpringMVC的工作原理,具体过程如下:

1)、客户端发送http请求给web服务器,web服务器对http请求进行解析,如果匹配到web.xml中dispatcherServlet对应的请求映射路径,则web服务器将请求转交给DispatcherServlet

如下图:

2)、DispatcherServlet接收到请求后根据请求的信息(包括请求URL、Http方法、请求报文头和请求参数Cookie等)和 HandlerMapping 中的映射配置找到处理请求的处理器 Handler

3)、DispatcherServlet将处理权交给 Handler, 然后根据 Handler 和 handlerAdapters 找到对应的 HandlerAdapter

4)、HandlerAdapter 对 Handler 进行具体的调用,处理http请求

5)、Handler 对请求处理完成以后将返回一个 ModelAndView 对象给 DispatcherServlet,这个 ModelAndView 只是一个逻辑视图而不是一个真正意义上的视图

6)、DispatcherServlet 通过 ViewResolver 将 ModelAndView 转化为真正的视图 view

7)、DispatcherServlet 调用 View 的 render 方法(传参是 ModelAndView 中 Model)渲染 View 并返回给客户端

从SpringMVC工作原理可知,主要的工作就是在 DispatcherServlet 完成的,下面学习一下 DispatcherServlet 源码

三、DispatcherServlet 源码

3.1 初始化工作

DispatcherServlet 在初始化屎主要完成了所有策略的初始化,比如 MultipartResolver、HandlerMapping、HandlerAdapter 等,所有默认的策略配置在 DispatcherServlet.properties 文件中,如下图:

初始化过程源码如下:

	// 1、加载DispatcherServlet.properties 配置文件
	static {
		// Load default strategy implementations from properties file.
		// This is currently strictly internal and not meant to be customized
		// by application developers.
		try {
			// 加载 resources/org/springframework/web/servlet 目录下的 DispatcherServlet.properties 配置文件,加载默认策略
			ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
			defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
		}
		catch (IOException ex) {
			throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());
		}
	}


	/**
	 * This implementation calls {@link #initStrategies}.
	 */
	// 2、onRefresh 方法初始化所有的策略
	@Override
	protected void onRefresh(ApplicationContext context) {
		// 初始化策略
		initStrategies(context);
	}

	/**
	 * Initialize the strategy objects that this servlet uses.
	 * <p>May be overridden in subclasses in order to initialize further strategy objects.
	 */
	protected void initStrategies(ApplicationContext context) {
		// 初始化上传文件解析器
		initMultipartResolver(context);
		// 初始化本地解析器,默认 AcceptHeaderLocaleResolver
		initLocaleResolver(context);
		// 初始化主题解析器,默认 FixedThemeResolver
		initThemeResolver(context);
		// 初始化HandlerMappings,默认 BeanNameUrlHandlerMapping
		initHandlerMappings(context);
		// 初始化HandlerAdapters,默认 SimpleControllerHandlerAdapter
		initHandlerAdapters(context);
		// 初始化异常处理器解析器,默认 DefaultHandlerExceptionResolver
		initHandlerExceptionResolvers(context);
		// 初始化RequestToViewNameTranslator,默认 DefaultRequestToViewNameTranslator
		initRequestToViewNameTranslator(context);
		// 初始化视图解析器,默认 InternalResourceViewResolver
		initViewResolvers(context);
		// 初始化FlashMapManager,默认 DefaultFlashMapManager
		initFlashMapManager(context);
	}

	/**
	 * Initialize the MultipartResolver used by this class.
	 * <p>If no bean is defined with the given name in the BeanFactory for this namespace,
	 * no multipart handling is provided.
	 */
	private void initMultipartResolver(ApplicationContext context) {
		try {
			// 从Spring容器中获取名称为 multipartResolver && 类型是 MultipartResolver 的 MultipartResolver
			this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Detected " + this.multipartResolver);
			}
			else if (logger.isDebugEnabled()) {
				logger.debug("Detected " + this.multipartResolver.getClass().getSimpleName());
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// Default is no multipart resolver.
			this.multipartResolver = null;
			if (logger.isTraceEnabled()) {
				logger.trace("No MultipartResolver '" + MULTIPART_RESOLVER_BEAN_NAME + "' declared");
			}
		}
	}

	/**
	 * Initialize the LocaleResolver used by this class.
	 * <p>If no bean is defined with the given name in the BeanFactory for this namespace,
	 * we default to AcceptHeaderLocaleResolver.
	 */
	private void initLocaleResolver(ApplicationContext context) {
		try {
			// 从Spring容器中获取名称为 localeResolver && 类型是 LocaleResolver 的 LocaleResolver
			this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Detected " + this.localeResolver);
			}
			else if (logger.isDebugEnabled()) {
				logger.debug("Detected " + this.localeResolver.getClass().getSimpleName());
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// We need to use the default.
			// 使用默认 AcceptHeaderLocaleResolver
			this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
			if (logger.isTraceEnabled()) {
				logger.trace("No LocaleResolver '" + LOCALE_RESOLVER_BEAN_NAME +
						"': using default [" + this.localeResolver.getClass().getSimpleName() + "]");
			}
		}
	}

	/**
	 * Initialize the ThemeResolver used by this class.
	 * <p>If no bean is defined with the given name in the BeanFactory for this namespace,
	 * we default to a FixedThemeResolver.
	 */
	private void initThemeResolver(ApplicationContext context) {
		try {
			// 从Spring容器中获取名称为 themeResolver && 类型是 ThemeResolver 的 ThemeResolver
			this.themeResolver = context.getBean(THEME_RESOLVER_BEAN_NAME, ThemeResolver.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Detected " + this.themeResolver);
			}
			else if (logger.isDebugEnabled()) {
				logger.debug("Detected " + this.themeResolver.getClass().getSimpleName());
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// We need to use the default.
			// 使用默认的 FixedThemeResolver
			this.themeResolver = getDefaultStrategy(context, ThemeResolver.class);
			if (logger.isTraceEnabled()) {
				logger.trace("No ThemeResolver '" + THEME_RESOLVER_BEAN_NAME +
						"': using default [" + this.themeResolver.getClass().getSimpleName() + "]");
			}
		}
	}

	/**
	 * Initialize the HandlerMappings used by this class.
	 * <p>If no HandlerMapping beans are defined in the BeanFactory for this namespace,
	 * we default to BeanNameUrlHandlerMapping.
	 */
	private void initHandlerMappings(ApplicationContext context) {
		this.handlerMappings = null;

		// detectAllHandlerMappings 默认为true,检测所有的 HandlerMapping
		if (this.detectAllHandlerMappings) {
			// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
			// 从 ApplicationContext 上下文 或者 祖先上下文中获取所有的 HandlerMapping
			Map<String, HandlerMapping> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerMappings = new ArrayList<>(matchingBeans.values());
				// We keep HandlerMappings in sorted order.
				// 对 HandlerMapping 排序
				AnnotationAwareOrderComparator.sort(this.handlerMappings);
			}
		}
		else {
			// detectAllHandlerMappings 为false 时
			try {
				// 从Spring容器中获取名称为 handlerMapping && 类型是 HandlerMapping 的 HandlerMapping
				HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
				this.handlerMappings = Collections.singletonList(hm);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default HandlerMapping later.
			}
		}

		// Ensure we have at least one HandlerMapping, by registering
		// a default HandlerMapping if no other mappings are found.
		if (this.handlerMappings == null) {
			// 使用默认的 BeanNameUrlHandlerMapping
			this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
			if (logger.isTraceEnabled()) {
				logger.trace("No HandlerMappings declared for servlet '" + getServletName() +
						"': using default strategies from DispatcherServlet.properties");
			}
		}
	}

	/**
	 * Initialize the HandlerAdapters used by this class.
	 * <p>If no HandlerAdapter beans are defined in the BeanFactory for this namespace,
	 * we default to SimpleControllerHandlerAdapter.
	 */
	private void initHandlerAdapters(ApplicationContext context) {
		this.handlerAdapters = null;

		// detectAllHandlerAdapters 默认为true,检测所有的 HandlerAdapter
		if (this.detectAllHandlerAdapters) {
			// Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
			// 从 ApplicationContext 上下文 或者 祖先上下文中获取所有的 HandlerAdapter
			Map<String, HandlerAdapter> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerAdapters = new ArrayList<>(matchingBeans.values());
				// We keep HandlerAdapters in sorted order.
				// 对 HandlerAdapter 排序
				AnnotationAwareOrderComparator.sort(this.handlerAdapters);
			}
		}
		else {
			// detectAllHandlerAdapters 为false
			try {
				// 从Spring容器中获取名称为 handlerAdapter && 类型是 HandlerAdapter 的 HandlerAdapter
				HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
				this.handlerAdapters = Collections.singletonList(ha);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default HandlerAdapter later.
			}
		}

		// Ensure we have at least some HandlerAdapters, by registering
		// default HandlerAdapters if no other adapters are found.
		if (this.handlerAdapters == null) {
			// 使用默认的 SimpleControllerHandlerAdapter
			this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
			if (logger.isTraceEnabled()) {
				logger.trace("No HandlerAdapters declared for servlet '" + getServletName() +
						"': using default strategies from DispatcherServlet.properties");
			}
		}
	}

	/**
	 * Initialize the HandlerExceptionResolver used by this class.
	 * <p>If no bean is defined with the given name in the BeanFactory for this namespace,
	 * we default to no exception resolver.
	 */
	private void initHandlerExceptionResolvers(ApplicationContext context) {
		this.handlerExceptionResolvers = null;

		// detectAllHandlerExceptionResolvers 默认为true,检测所有的 HandlerExceptionResolver
		if (this.detectAllHandlerExceptionResolvers) {
			// Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts.
			// 从 ApplicationContext 上下文 或者 祖先上下文中获取所有的 HandlerExceptionResolver
			Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils
					.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerExceptionResolvers = new ArrayList<>(matchingBeans.values());
				// We keep HandlerExceptionResolvers in sorted order.
				// 对 HandlerExceptionResolver 排序
				AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
			}
		}
		else {
			try {
				// 从Spring容器中获取名称为 handlerExceptionResolver && 类型是 HandlerExceptionResolver 的 HandlerExceptionResolver
				HandlerExceptionResolver her =
						context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class);
				this.handlerExceptionResolvers = Collections.singletonList(her);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, no HandlerExceptionResolver is fine too.
			}
		}

		// Ensure we have at least some HandlerExceptionResolvers, by registering
		// default HandlerExceptionResolvers if no other resolvers are found.
		if (this.handlerExceptionResolvers == null) {
			// 使用默认的 DefaultHandlerExceptionResolver
			this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class);
			if (logger.isTraceEnabled()) {
				logger.trace("No HandlerExceptionResolvers declared in servlet '" + getServletName() +
						"': using default strategies from DispatcherServlet.properties");
			}
		}
	}

	/**
	 * Initialize the RequestToViewNameTranslator used by this servlet instance.
	 * <p>If no implementation is configured then we default to DefaultRequestToViewNameTranslator.
	 */
	private void initRequestToViewNameTranslator(ApplicationContext context) {
		try {
			// 从Spring容器中获取名称为 viewNameTranslator && 类型是 RequestToViewNameTranslator 的 RequestToViewNameTranslator
			this.viewNameTranslator =
					context.getBean(REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME, RequestToViewNameTranslator.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Detected " + this.viewNameTranslator.getClass().getSimpleName());
			}
			else if (logger.isDebugEnabled()) {
				logger.debug("Detected " + this.viewNameTranslator);
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// We need to use the default.
			// 使用默认的 DefaultRequestToViewNameTranslator
			this.viewNameTranslator = getDefaultStrategy(context, RequestToViewNameTranslator.class);
			if (logger.isTraceEnabled()) {
				logger.trace("No RequestToViewNameTranslator '" + REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME +
						"': using default [" + this.viewNameTranslator.getClass().getSimpleName() + "]");
			}
		}
	}

	/**
	 * Initialize the ViewResolvers used by this class.
	 * <p>If no ViewResolver beans are defined in the BeanFactory for this
	 * namespace, we default to InternalResourceViewResolver.
	 */
	private void initViewResolvers(ApplicationContext context) {
		this.viewResolvers = null;

		// detectAllViewResolvers 默认为true,检测所有的 ViewResolver
		if (this.detectAllViewResolvers) {
			// Find all ViewResolvers in the ApplicationContext, including ancestor contexts.
			// 从 ApplicationContext 上下文 或者 祖先上下文中获取所有的 ViewResolver
			Map<String, ViewResolver> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.viewResolvers = new ArrayList<>(matchingBeans.values());
				// We keep ViewResolvers in sorted order.
				// 对 ViewResolver 排序
				AnnotationAwareOrderComparator.sort(this.viewResolvers);
			}
		}
		else {
			// detectAllViewResolvers 为false
			try {
				// 从Spring容器中获取名称为 viewResolver && 类型是 ViewResolver 的 ViewResolver
				ViewResolver vr = context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class);
				this.viewResolvers = Collections.singletonList(vr);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default ViewResolver later.
			}
		}

		// Ensure we have at least one ViewResolver, by registering
		// a default ViewResolver if no other resolvers are found.
		if (this.viewResolvers == null) {
			// 使用默认的 InternalResourceViewResolver
			this.viewResolvers = getDefaultStrategies(context, ViewResolver.class);
			if (logger.isTraceEnabled()) {
				logger.trace("No ViewResolvers declared for servlet '" + getServletName() +
						"': using default strategies from DispatcherServlet.properties");
			}
		}
	}

	/**
	 * Initialize the {@link FlashMapManager} used by this servlet instance.
	 * <p>If no implementation is configured then we default to
	 * {@code org.springframework.web.servlet.support.DefaultFlashMapManager}.
	 */
	private void initFlashMapManager(ApplicationContext context) {
		try {
			// 从Spring容器中获取名称为 flashMapManager && 类型是 FlashMapManager 的 FlashMapManager
			this.flashMapManager = context.getBean(FLASH_MAP_MANAGER_BEAN_NAME, FlashMapManager.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Detected " + this.flashMapManager.getClass().getSimpleName());
			}
			else if (logger.isDebugEnabled()) {
				logger.debug("Detected " + this.flashMapManager);
			}
		}
		catch (NoSuchBeanDefinitionException ex) {
			// We need to use the default.
			// 使用默认的 DefaultFlashMapManager
			this.flashMapManager = getDefaultStrategy(context, FlashMapManager.class);
			if (logger.isTraceEnabled()) {
				logger.trace("No FlashMapManager '" + FLASH_MAP_MANAGER_BEAN_NAME +
						"': using default [" + this.flashMapManager.getClass().getSimpleName() + "]");
			}
		}
	}


	/**
	 * Return the default strategy object for the given strategy interface.
	 * <p>The default implementation delegates to {@link #getDefaultStrategies},
	 * expecting a single object in the list.
	 * @param context the current WebApplicationContext
	 * @param strategyInterface the strategy interface
	 * @return the corresponding strategy object
	 * @see #getDefaultStrategies
	 */
	// 3、获取 DispatcherServlet.properties 文件中定义的默认策略
	protected <T> T getDefaultStrategy(ApplicationContext context, Class<T> strategyInterface) {
		List<T> strategies = getDefaultStrategies(context, strategyInterface);
		if (strategies.size() != 1) {
			// 默认策略大于1时抛出异常
			throw new BeanInitializationException(
					"DispatcherServlet needs exactly 1 strategy for interface [" + strategyInterface.getName() + "]");
		}
		return strategies.get(0);
	}

	/**
	 * Create a List of default strategy objects for the given strategy interface.
	 * <p>The default implementation uses the "DispatcherServlet.properties" file (in the same
	 * package as the DispatcherServlet class) to determine the class names. It instantiates
	 * the strategy objects through the context's BeanFactory.
	 * @param context the current WebApplicationContext
	 * @param strategyInterface the strategy interface
	 * @return the List of corresponding strategy objects
	 */
	@SuppressWarnings("unchecked")
	protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
		// 类全限定名作为key
		String key = strategyInterface.getName();
		// 从配置文件获取key对应的值
		String value = defaultStrategies.getProperty(key);
		if (value != null) {
			// 以逗号分隔多个值
			String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
			List<T> strategies = new ArrayList<>(classNames.length);
			for (String className : classNames) {
				try {
					// 反射实例化对象
					Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
					// 创建默认的策略
					Object strategy = createDefaultStrategy(context, clazz);
					strategies.add((T) strategy);
				}
				catch (ClassNotFoundException ex) {
					throw new BeanInitializationException(
							"Could not find DispatcherServlet's default strategy class [" + className +
							"] for interface [" + key + "]", ex);
				}
				catch (LinkageError err) {
					throw new BeanInitializationException(
							"Unresolvable class definition for DispatcherServlet's default strategy class [" +
							className + "] for interface [" + key + "]", err);
				}
			}
			return strategies;
		}
		else {
			return new LinkedList<>();
		}
	}

DispatcherServlet 初始化期间完成了所有策略的初始化,源码注释写的很详细,这里就不在赘述了

接下来我们看 DispatcherServlet 处理 request 请求过程

3.2  处理请求

DispatcherServlet 处理 request 请求的入口在 doService 方法中,源码如下:

	/**
	 * Exposes the DispatcherServlet-specific request attributes and delegates to {@link #doDispatch}
	 * for the actual dispatching.
	 */
	@Override
	protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 记录Request请求日志
		logRequest(request);

		// Keep a snapshot of the request attributes in case of an include,
		// to be able to restore the original attributes after the include.
		// 保存请求快照,以便恢复request的原始属性
		Map<String, Object> attributesSnapshot = null;
		if (WebUtils.isIncludeRequest(request)) {
			attributesSnapshot = new HashMap<>();
			Enumeration<?> attrNames = request.getAttributeNames();
			while (attrNames.hasMoreElements()) {
				String attrName = (String) attrNames.nextElement();
				if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {
					attributesSnapshot.put(attrName, request.getAttribute(attrName));
				}
			}
		}

		// Make framework objects available to handlers and view objects.
		// request 中添加一些属性,比如 org.springframework.web.servlet.DispatcherServlet.CONTEXT 等
		request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
		request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
		request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
		request.setAttribute(THEME_SOURCE_ATTRIBUTE, 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 {
			// 真正处理 request 请求逻辑
			doDispatch(request, response);
		}
		finally {
			if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
				// Restore the original attribute snapshot, in case of an include.
				if (attributesSnapshot != null) {
					// 从保存的快照中恢复request的原始属性
					restoreAttributesAfterInclude(request, attributesSnapshot);
				}
			}
		}
	}


	/**
	 * Process the actual dispatching to the handler.
	 * <p>The handler will be obtained by applying the servlet's HandlerMappings in order.
	 * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters
	 * to find the first that supports the handler class.
	 * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers
	 * themselves to decide which methods are acceptable.
	 * @param request current HTTP request
	 * @param response current HTTP response
	 * @throws Exception in case of any kind of processing failure
	 */
	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 {
				// 检测 request 的 header 中的 ContentType 属性值是否以 multipart/ 开头,如果是 request 转成 MultipartHttpServletRequest
				processedRequest = checkMultipart(request);
				// 记录是否是 MultipartHttpServletRequest
				multipartRequestParsed = (processedRequest != request);

				// Determine handler for the current request.
				// 1、根据 request 从 handlerMappings 中获取 Handler,即 HandlerExecutionChain
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null) {
					noHandlerFound(processedRequest, response);
					return;
				}

				// Determine handler adapter for the current request.
				// 2、根据 Handler 从 handlerAdapters 中获取 HandlerAdapter(RequestMappingHandlerAdapter)
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

				// Process last-modified header, if supported by the handler.
				// 获取请求方法,例如 GET、POST、PUT、DELETED 等
				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) {
						// 最近更新时间没有变化的话,说明是重复请求 request,则不需要做处理
						return;
					}
				}

				// 3、对request请求做前置拦截处理,即调用处理器链中的所有拦截器 HandlerInterceptor 的 preHandle 方法
				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}

				// Actually invoke the handler.
				// 4、调用 RequestMappingHandlerAdapter 的 handle 方法处理 request,并返回 ModelAndView
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

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

				// ModelAndView 中设置默认 viewName 属性
				applyDefaultViewName(processedRequest, mv);
				// 5、对request请求做后置拦截处理,即调用处理器链中的所有拦截器 HandlerInterceptor 的 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);
			}
			// 6、处理请求结果,即通过 ViewResolver 将 ModelAndView 转成 View,并调用 View 的 render 方法渲染 view
			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 afterCompletion
				if (mappedHandler != null) {
					// 调用处理器链中的所有异步拦截器 AsyncHandlerInterceptor 的 afterConcurrentHandlingStarted 方法
					mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
				}
			}
			else {
				// Clean up any resources used by a multipart request.
				// 清除 MultipartHttpServletRequest 使用的任何资源
				if (multipartRequestParsed) {
					cleanupMultipart(processedRequest);
				}
			}
		}
	}

DispatcherServlet 处理 request 共经过了以下六个步骤:

1)、根据 request 从 handlerMappings 中获取 Handler,即 HandlerExecutionChain

2)、根据 Handler 从 handlerAdapters 中获取 HandlerAdapter,这里指的是 RequestMappingHandlerAdapter

3)、对request请求做前置拦截处理,即调用处理器链中的所有拦截器 HandlerInterceptor 的 preHandle 方法

4)、调用 RequestMappingHandlerAdapter 的 handle 方法处理 request,并返回 ModelAndView

5)、对request请求做后置拦截处理,即调用处理器链中的所有拦截器 HandlerInterceptor 的 postHandle 方法

6)、处理请求结果,即通过 ViewResolver 将 ModelAndView 转成 View,并调用 View 的 render 方法渲染 view

下面从源码方面分别对这六个步骤解析

3.2.1 获取 Handler(HandlerExecutionChain)

获取 Handler 的业务逻辑在 DispatcherServlet 的 getHandler 的方法实现了,getHandler 源码如下:

	/**
	 * Return the HandlerExecutionChain for this request.
	 * <p>Tries all handler mappings in order.
	 * @param request current HTTP request
	 * @return the HandlerExecutionChain, or {@code null} if no handler could be found
	 */
	// 1、DispatcherServlet 的 getHandler 方法
	@Nullable
	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		if (this.handlerMappings != null) {
			for (HandlerMapping mapping : this.handlerMappings) {
				// 调用 AbstractHandlerMapping 的 getHandler 方法获取 HandlerExecutionChain
				HandlerExecutionChain handler = mapping.getHandler(request);
				if (handler != null) {
					return handler;
				}
			}
		}
		return null;
	}


	/**
	 * Look up a handler for the given request, falling back to the default
	 * handler if no specific one is found.
	 * @param request current HTTP request
	 * @return the corresponding handler instance, or the default handler
	 * @see #getHandlerInternal
	 */
	// 2、AbstractHandlerMapping 的 getHandler 方法
	@Override
	@Nullable
	public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		// 调用 AbstractHandlerMethodMapping 的 getHandlerInternal 方法获取 HandlerMethod
		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;
			// String 类型的 ,直接从上下文中根据名字获取实例
			handler = obtainApplicationContext().getBean(handlerName);
		}

		// 根据 request 请求 url 获取匹配的所有拦截器,并将 handler 和拦截器封装到 HandlerExecutionChain 对象中
		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 (hasCorsConfigurationSource(handler)) {
			CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);
			CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
			config = (config != null ? config.combine(handlerConfig) : handlerConfig);
			// 调用 AbstractHandlerMapping 的 getCorsHandlerExecutionChain 方法
			executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
		}

		return executionChain;
	}


	// AbstractHandlerMapping 的 getHandlerExecutionChain 方法
	protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
		HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
				(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

		// 获取请求url
		String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, LOOKUP_PATH);
		for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
			if (interceptor instanceof MappedInterceptor) {
				MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
				// HandlerInterceptor 是 MappedInterceptor 类型 && 请求url 匹配符合 HandlerInterceptor 的 拦截路径规则
				if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
					// 添加 HandlerInterceptor 到 HandlerExecutionChain 中
					chain.addInterceptor(mappedInterceptor.getInterceptor());
				}
			}
			else {
				// 不需要匹配url路径规则的 HandlerInterceptor 直接添加到 HandlerExecutionChain 中
				chain.addInterceptor(interceptor);
			}
		}
		return chain;
	}


	// AbstractHandlerMapping 的 getCorsHandlerExecutionChain 方法
	protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request,
			HandlerExecutionChain chain, @Nullable CorsConfiguration config) {
		if (CorsUtils.isPreFlightRequest(request)) {
			// request 的 method 是 OPTIONs && request 的 header 中有 Access-Control-Request-Method
			HandlerInterceptor[] interceptors = chain.getInterceptors();
			chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors);
		}
		else {
			// 否则的话,将 CorsInterceptor 拦截器设置为第一个元素
			chain.addInterceptor(0, new CorsInterceptor(config));
		}
		return chain;
	}


	/**
	 * Look up a handler method for the given request.
	 */
	// 3、AbstractHandlerMethodMapping 的 getHandlerInternal 方法
	@Override
	protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
		// 获取请求 url
		String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
		request.setAttribute(LOOKUP_PATH, lookupPath);
		// 对映射关系注册对象加锁,防止获取HandlerMethod的时候注册对象被其他线程读取
		this.mappingRegistry.acquireReadLock();
		try {
			// 调用 lookupHandlerMethod 方法 获取 HandlerMethod
			HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
			return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
		}
		finally {
			this.mappingRegistry.releaseReadLock();
		}
	}

	/**
	 * Look up the best-matching handler method for the current request.
	 * If multiple matches are found, the best match is selected.
	 * @param lookupPath mapping lookup path within the current servlet mapping
	 * @param request the current request
	 * @return the best-matching handler method, or {@code null} if no match
	 * @see #handleMatch(Object, String, HttpServletRequest)
	 * @see #handleNoMatch(Set, String, HttpServletRequest)
	 */
	// AbstractHandlerMethodMapping 的 lookupHandlerMethod 方法
	@Nullable
	protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
		List<Match> matches = new ArrayList<>();
		// 根据请求url获取直接匹配列表
		List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
		if (directPathMatches != null) {
			addMatchingMappings(directPathMatches, matches, request);
		}
		if (matches.isEmpty()) {
			// No choice but to go through all mappings...
			addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
		}

		if (!matches.isEmpty()) {
			Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
			// 匹配排序
			matches.sort(comparator);
			Match bestMatch = matches.get(0);
			// 请求url匹配到多个规则时,取前两个规则比较,不相同的话,取第一个匹配规则作为最终结果
			if (matches.size() > 1) {
				if (logger.isTraceEnabled()) {
					logger.trace(matches.size() + " matching mappings: " + matches);
				}
				if (CorsUtils.isPreFlightRequest(request)) {
					return PREFLIGHT_AMBIGUOUS_MATCH;
				}
				// 多个都匹配请求url时,比较前两个是否相等,相等的话抛出异常
				Match secondBestMatch = matches.get(1);
				if (comparator.compare(bestMatch, secondBestMatch) == 0) {
					Method m1 = bestMatch.handlerMethod.getMethod();
					Method m2 = secondBestMatch.handlerMethod.getMethod();
					String uri = request.getRequestURI();
					throw new IllegalStateException(
							"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
				}
			}
			// 添加匹配的 HandlerMethod 到 request 的 attribute 属性中
			request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);
			handleMatch(bestMatch.mapping, lookupPath, request);
			return bestMatch.handlerMethod;
		}
		else {
			return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
		}
	}

RequestMapping 注解对应的url和Controller中的方法映射关系如下图:

获取 Handler 的逻辑相对来说不太复杂,代码注释写的很明白了,直接看源码就可以理解整个过程了

3.2.2 获取 HandlerAdapter(RequestMappingHandlerAdapter)

获取 HandlerAdapter 的业务逻辑入口在 DispatcherServlet 的 getHandlerAdapter 方法,真个过程源码如下:

	/**
	 * Return the HandlerAdapter for this handler object.
	 * @param handler the handler object to find an adapter for
	 * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error.
	 */
	// 1、DispatcherServlet 的 getHandlerAdapter 方法
	protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
		if (this.handlerAdapters != null) {
			for (HandlerAdapter adapter : this.handlerAdapters) {
				// 调用的是 AbstractHandlerMethodAdapter 的 supports 方法
				if (adapter.supports(handler)) {
					// HandlerAdapter 支持 handler,返回该 HandlerAdapter,这里是 RequestMappingHandlerAdapter
					return adapter;
				}
			}
		}
		throw new ServletException("No adapter for handler [" + handler +
				"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
	}


	/**
	 * This implementation expects the handler to be an {@link HandlerMethod}.
	 * @param handler the handler instance to check
	 * @return whether or not this adapter can adapt the given handler
	 */
	// 2、AbstractHandlerMethodAdapter 的 supports 方法
	@Override
	public final boolean supports(Object handler) {
		// 判断 handler 是否是 HandlerMethod 类型
		// 调用 RequestMappingHandlerAdapter 的 supportsInternal 方法,永远返回 true
		return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
	}


	/**
	 * Always return {@code true} since any method argument and return value
	 * type will be processed in some way. A method argument not recognized
	 * by any HandlerMethodArgumentResolver is interpreted as a request parameter
	 * if it is a simple type, or as a model attribute otherwise. A return value
	 * not recognized by any HandlerMethodReturnValueHandler will be interpreted
	 * as a model attribute.
	 */
	// 3、RequestMappingHandlerAdapter 的 supportsInternal 方法
	@Override
	protected boolean supportsInternal(HandlerMethod handlerMethod) {
		return true;
	}

获取 HandlerAdapter 逻辑十分简单,主要就是根据 Handler 获取到了 RequestMappingHandlerAdapter,这里不在赘述

3.2.3 调用 (HandlerAdapter)RequestMappingHandlerAdapter 的 handle 方法返回 ModelAndView

这个过程是整个 SpringMVC 的核心所在,这个过程体现了通过浏览器发起的请求是怎么样最后交给 Controller 的 方法处理的,整体debug栈信息如下:

invoke:498, Method (java.lang.reflect)
doInvoke:205, InvocableHandlerMethod (org.springframework.web.method.support)
invokeForRequest:133, InvocableHandlerMethod (org.springframework.web.method.support)
invokeAndHandle:97, ServletInvocableHandlerMethod (org.springframework.web.servlet.mvc.method.annotation)
invokeHandlerMethod:849, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handleInternal:760, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handle:85, AbstractHandlerMethodAdapter (org.springframework.web.servlet.mvc.method)
doDispatch:967, DispatcherServlet (org.springframework.web.servlet)
doService:901, DispatcherServlet (org.springframework.web.servlet)
processRequest:970, FrameworkServlet (org.springframework.web.servlet)
doPost:872, FrameworkServlet (org.springframework.web.servlet)
service:660, HttpServlet (javax.servlet.http)
service:846, FrameworkServlet (org.springframework.web.servlet)
service:741, HttpServlet (javax.servlet.http)
internalDoFilter:231, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:53, WsFilter (org.apache.tomcat.websocket.server)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilter:31, AccessControlFilter (com.ideacome.black.pearl.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
doFilterInternal:197, CharacterEncodingFilter (org.springframework.web.filter)
doFilter:107, OncePerRequestFilter (org.springframework.web.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
invoke:199, StandardWrapperValve (org.apache.catalina.core)
invoke:96, StandardContextValve (org.apache.catalina.core)
invoke:490, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:139, StandardHostValve (org.apache.catalina.core)
invoke:92, ErrorReportValve (org.apache.catalina.valves)
invoke:668, AbstractAccessLogValve (org.apache.catalina.valves)
invoke:74, StandardEngineValve (org.apache.catalina.core)
service:343, CoyoteAdapter (org.apache.catalina.connector)
service:408, Http11Processor (org.apache.coyote.http11)
process:66, AbstractProcessorLight (org.apache.coyote)
process:770, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1415, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1149, ThreadPoolExecutor (java.util.concurrent)
run:624, ThreadPoolExecutor$Worker (java.util.concurrent)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:748, Thread (java.lang)

通过栈信息可以得出如下结论:

1)、request 请求首先进入到 tomcat(使用的是tomcat web容器)容器中,经过了 tomcat 的层层处理

2)、tomcat 处理请求后将 request 交给了 Spring 容器的 FrameworkServlet 处理

3)、request 最终被 Spring 容器的 DispatcherServlet(继承 FrameworkServlet) 处理

4)、在 DispatcherServlet 中 RequestMappingHandlerAdapter 通过请求url定位到具体的Controller的具体方法

5)、最后通过反射调用对象方法,即调用到了Controller的具体方法

调用 HandlerAdapter 的 handle 方法入口是 AbstractHandlerMethodAdapter 的 handle 方法,整个过程源码如下:

	/**
	 * This implementation expects the handler to be an {@link HandlerMethod}.
	 */
	// 1、AbstractHandlerMethodAdapter 的 handle 方法
	@Override
	@Nullable
	public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// 调用 RequestMappingHandlerAdapter 的 handleInternal 方法处理请求
		return handleInternal(request, response, (HandlerMethod) handler);
	}


	// 2、RequestMappingHandlerAdapter 的 handleInternal 方法
	@Override
	protected ModelAndView handleInternal(HttpServletRequest request,
			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

		ModelAndView mav;
		// 检测是否支持 request 的 method 方法
		checkRequest(request);

		// Execute invokeHandlerMethod in synchronized block if required.
		// 是否在同步块中执行 invokeHandlerMethod
		if (this.synchronizeOnSession) {
			HttpSession session = request.getSession(false);
			if (session != null) {
				Object mutex = WebUtils.getSessionMutex(session);
				synchronized (mutex) {
					mav = invokeHandlerMethod(request, response, handlerMethod);
				}
			}
			else {
				// No HttpSession available -> no mutex necessary
				mav = invokeHandlerMethod(request, response, handlerMethod);
			}
		}
		else {
			// No synchronization on session demanded at all...
			// 继续调用 RequestMappingHandlerAdapter 的 invokeHandlerMethod
			mav = invokeHandlerMethod(request, response, handlerMethod);
		}

		if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
			if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
				applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
			}
			else {
				// response 中的缓存 Cache-Control 设置
				prepareResponse(response);
			}
		}

		return mav;
	}


	/**
	 * Invoke the {@link RequestMapping} handler method preparing a {@link ModelAndView}
	 * if view resolution is required.
	 * @since 4.2
	 * @see #createInvocableHandlerMethod(HandlerMethod)
	 */
	// 3、RequestMappingHandlerAdapter 的 invokeHandlerMethod
	@Nullable
	protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

		// 构建 ServletWebRequest 对象
		ServletWebRequest webRequest = new ServletWebRequest(request, response);
		try {
			WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
			ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

			// 构建 ServletInvocableHandlerMethod 对象
			ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
			if (this.argumentResolvers != null) {
				invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
			}
			if (this.returnValueHandlers != null) {
				invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
			}
			invocableMethod.setDataBinderFactory(binderFactory);
			invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);

			// 构建 ModelAndView 容器
			ModelAndViewContainer mavContainer = new ModelAndViewContainer();
			mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
			modelFactory.initModel(webRequest, mavContainer, invocableMethod);
			mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

			// 构建异步web请求
			AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
			asyncWebRequest.setTimeout(this.asyncRequestTimeout);

			WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
			asyncManager.setTaskExecutor(this.taskExecutor);
			asyncManager.setAsyncWebRequest(asyncWebRequest);
			asyncManager.registerCallableInterceptors(this.callableInterceptors);
			asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);

			if (asyncManager.hasConcurrentResult()) {
				Object result = asyncManager.getConcurrentResult();
				mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
				asyncManager.clearConcurrentResult();
				LogFormatUtils.traceDebug(logger, traceOn -> {
					String formatted = LogFormatUtils.formatValue(result, !traceOn);
					return "Resume with async result [" + formatted + "]";
				});
				invocableMethod = invocableMethod.wrapConcurrentResult(result);
			}

			// 调用 ServletInvocableHandlerMethod 的 invokeAndHandle 方法处理请求
			invocableMethod.invokeAndHandle(webRequest, mavContainer);
			if (asyncManager.isConcurrentHandlingStarted()) {
				return null;
			}

			// 调用 getModelAndView 方法获取 ModelAndView 
			return getModelAndView(mavContainer, modelFactory, webRequest);
		}
		finally {
			webRequest.requestCompleted();
		}
	}

	/**
	 * Invoke the method and handle the return value through one of the
	 * configured {@link HandlerMethodReturnValueHandler HandlerMethodReturnValueHandlers}.
	 * @param webRequest the current request
	 * @param mavContainer the ModelAndViewContainer for this request
	 * @param providedArgs "given" arguments matched by type (not resolved)
	 */
	// 4、ServletInvocableHandlerMethod 的 invokeAndHandle 方法
	public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {

		// 调用 InvocableHandlerMethod 的 invokeForRequest 方法处理请求并获取返回值
		Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
		// 设置请求响应状态
		setResponseStatus(webRequest);

		// 返回值为null
		if (returnValue == null) {
			// 重复请求 或者 响应状态不为空 或者 已经全部处理好了
			if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
				disableContentCachingIfNecessary(webRequest);
				// requestHandled 设置为 true,即不需要返回 ModelAndView
				mavContainer.setRequestHandled(true);
				return;
			}
		}
		else if (StringUtils.hasText(getResponseStatusReason())) {
			// 响应状态有原因时,requestHandled 设置为 true,即不需要返回 ModelAndView
			mavContainer.setRequestHandled(true);
			return;
		}

		mavContainer.setRequestHandled(false);
		Assert.state(this.returnValueHandlers != null, "No return value handlers");
		try {
			// 调用 HandlerMethodReturnValueHandlerComposite 的 handleReturnValue 对返回值处理
			this.returnValueHandlers.handleReturnValue(
					returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
		}
		catch (Exception ex) {
			if (logger.isTraceEnabled()) {
				logger.trace(formatErrorForReturnValue(returnValue), ex);
			}
			throw ex;
		}
	}

	// 5、InvocableHandlerMethod 的 invokeForRequest 方法
	@Nullable
	public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {

		// 获取请求方法的参数值
		Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
		if (logger.isTraceEnabled()) {
			logger.trace("Arguments: " + Arrays.toString(args));
		}
		// 调用 InvocableHandlerMethod 的 doInvoke 方法执行方法调用
		return doInvoke(args);
	}


		/**
	 * Invoke the handler method with the given argument values.
	 */
	// 6、InvocableHandlerMethod 的 doInvoke
	@Nullable
	protected Object doInvoke(Object... args) throws Exception {
		ReflectionUtils.makeAccessible(getBridgedMethod());
		try {
			// 通过反射调用 Method 的 invoke 方法,最终调用的是某个Controller的某个方法
			// 例如:TestController 的 test 方法
			return getBridgedMethod().invoke(getBean(), args);
		}
		catch (IllegalArgumentException ex) {
			assertTargetBean(getBridgedMethod(), getBean(), args);
			String text = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument");
			throw new IllegalStateException(formatInvokeError(text, args), ex);
		}
		catch (InvocationTargetException ex) {
			// Unwrap for HandlerExceptionResolvers ...
			Throwable targetException = ex.getTargetException();
			if (targetException instanceof RuntimeException) {
				throw (RuntimeException) targetException;
			}
			else if (targetException instanceof Error) {
				throw (Error) targetException;
			}
			else if (targetException instanceof Exception) {
				throw (Exception) targetException;
			}
			else {
				throw new IllegalStateException(formatInvokeError("Invocation failure", args), targetException);
			}
		}
	}


	/**
	 * Iterate over registered {@link HandlerMethodReturnValueHandler HandlerMethodReturnValueHandlers} and invoke the one that supports it.
	 * @throws IllegalStateException if no suitable {@link HandlerMethodReturnValueHandler} is found.
	 */
	// 7、HandlerMethodReturnValueHandlerComposite 的 handleReturnValue 对返回值处理
	@Override
	public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
		// 根据返回值和返回对象类型选择返回值对应的处理器,由于请求的Controller的方法是带有 ResponseBody 注解的 && 返回值类型是 Object
		// 因此这里获取的是 RequestResponseBodyMethodProcessor 
		HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
		if (handler == null) {
			throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
		}
		// 调用 RequestResponseBodyMethodProcessor 的 handleReturnValue 方法,将返回值转换为客户端需要的数据格式
		handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
	}

	@Nullable
	private HandlerMethodReturnValueHandler selectHandler(@Nullable Object value, MethodParameter returnType) {
		boolean isAsyncValue = isAsyncReturnValue(value, returnType);
		for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) {
			if (isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler)) {
				continue;
			}
			// 调用 RequestResponseBodyMethodProcessor 的 supportsReturnType 方法
			if (handler.supportsReturnType(returnType)) {
				// 选择处理器支持处理的返回对象类型对应的处理器,这里指 RequestResponseBodyMethodProcessor
				return handler;
			}
		}
		return null;
	}

	// RequestResponseBodyMethodProcessor 的 supportsReturnType 方法
	@Override
	public boolean supportsReturnType(MethodParameter returnType) {
		// 返回对象上是否有 ResponseBody 注解
		return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) ||
				returnType.hasMethodAnnotation(ResponseBody.class));
	}

	// 8、RequestResponseBodyMethodProcessor 的 handleReturnValue 方法
	@Override
	public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
			throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {

		// 将内部处理标识设置为 true,后续就不需要做额外的处理了,这里指的是获取 ModelAndView
		mavContainer.setRequestHandled(true);
		ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
		ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);

		// Try even with null return value. ResponseBodyAdvice could get involved.
		// 将返回值转换为客户端需要的数据格式
		writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
	}


	// 9、RequestMappingHandlerAdapter 的 getModelAndView 方法
	@Nullable
	private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
			ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {

		modelFactory.updateModel(webRequest, mavContainer);
		if (mavContainer.isRequestHandled()) {
			// 如果返回数据已经做了相应的处理了,这里就直接返回了
			return null;
		}
		// 获取填充数据 ModelMap
		ModelMap model = mavContainer.getModel();
		// 创建 ModelAndView
		ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
		if (!mavContainer.isViewReference()) {
			// 非String类型的 View,添加到 ModelAndView 属性中
			mav.setView((View) mavContainer.getView());
		}
		if (model instanceof RedirectAttributes) {
			Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();
			HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
			if (request != null) {
				RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
			}
		}
		// 返回 ModelAndView
		return mav;
	}





整个过程比较复杂,我是通过源码调试来学习整个过程的,希望大家多调试源码。代码中有详细的注释,这里就不再使用文字啰嗦了

3.2.4 对request请求做前后置拦截

1)、request 前置拦截

前置拦截就是调用处理器链中的所有拦截器 HandlerInterceptor 的 preHandle 方法,入口是 HandlerExecutionChain 的 applyPreHandle 方法,源码如下:

	/**
	 * Apply preHandle methods of registered interceptors.
	 * @return {@code true} if the execution chain should proceed with the
	 * next interceptor or the handler itself. Else, DispatcherServlet assumes
	 * that this interceptor has already dealt with the response itself.
	 */
	// HandlerExecutionChain 的 applyPreHandle 方法
	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HandlerInterceptor[] interceptors = getInterceptors();
		if (!ObjectUtils.isEmpty(interceptors)) {
			for (int i = 0; i < interceptors.length; i++) {
				HandlerInterceptor interceptor = interceptors[i];
				// 调用具体拦截器的 preHandle 方法
				if (!interceptor.preHandle(request, response, this.handler)) {
					// 如果前置拦截执行失败的话,则触发拦截器的最终处理
					triggerAfterCompletion(request, response, null);
					// 返回 false
					return false;
				}
				this.interceptorIndex = i;
			}
		}
		// 拦截器为空 或者 所有前置拦截执行成功,则返回 true
		return true;
	}

2)、request 后置拦截

前置拦截就是调用处理器链中的所有拦截器 HandlerInterceptor 的 postHandle 方法,入口是 HandlerExecutionChain 的 applyPostHandle方法,源码如下:

	/**
	 * Apply postHandle methods of registered interceptors.
	 */
	// HandlerExecutionChain 的 applyPostHandle 方法
	void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
			throws Exception {

		HandlerInterceptor[] interceptors = getInterceptors();
		if (!ObjectUtils.isEmpty(interceptors)) {
			for (int i = interceptors.length - 1; i >= 0; i--) {
				HandlerInterceptor interceptor = interceptors[i];
				// 调用具体拦截器的 postHandle 处理逻辑
				interceptor.postHandle(request, response, this.handler, mv);
			}
		}
	}

3)、request 完成之后拦截

完成之后拦截就是调用处理器链中的所有拦截器 HandlerInterceptor 的 afterCompletion 方法,入口是 HandlerExecutionChain 的 triggerAfterCompletion 方法,源码如下:

	// HandlerExecutionChain 的 triggerAfterCompletion 方法
	void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)
			throws Exception {

		HandlerInterceptor[] interceptors = getInterceptors();
		if (!ObjectUtils.isEmpty(interceptors)) {
			for (int i = this.interceptorIndex; i >= 0; i--) {
				HandlerInterceptor interceptor = interceptors[i];
				try {
					// 调用具体拦截器的 afterCompletion 方法
					interceptor.afterCompletion(request, response, this.handler, ex);
				}
				catch (Throwable ex2) {
					logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
				}
			}
		}
	}

拦截器 HandlerInterceptor 接口中定义了三个方法,即 preHandlerpostHandler afterCompletion

preHandler : Handler 执行前执行

postHandler : Handler 执行后执行

afterCompletion : view 渲染完成后执行

这里有一个注意的地方,如下:

当有一个 preHandler 执行失败返回 false 时,当前的请求将会 afterCompletion 方法,执行完后直接返回,handler 也将不会执行了

3.2.5 处理请求结果

DispatcherServlet 处理请求结果,这里有两个步骤,如下:

1)、ViewResolver 将 ModelAndView 转成 View

2)、调用 View 的 render 方法渲染 view

入口在 DispatcherServlet 的 processDispatchResult 方法,整个过程源码如下:

	/**
	 * Handle the result of handler selection and handler invocation, which is
	 * either a ModelAndView or an Exception to be resolved to a ModelAndView.
	 */
	// 1、DispatcherServlet 的 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);
				// 调用异常处理解析器来处理异常,并返回 ModelAndView
				mv = processHandlerException(request, response, handler, exception);
				errorView = (mv != null);
			}
		}

		// Did the handler return a view to render?
		// 是否返回要呈现给用户的视图
		if (mv != null && !mv.wasCleared()) {
			// 调用 DispatcherServlet 的 render 方法
			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) {
			// 触发请求request的完成之后的拦截处理
			mappedHandler.triggerAfterCompletion(request, response, null);
		}
	}


	/**
	 * Render the given ModelAndView.
	 * <p>This is the last stage in handling a request. It may involve resolving the view by name.
	 * @param mv the ModelAndView to render
	 * @param request current HTTP servlet request
	 * @param response current HTTP servlet response
	 * @throws ServletException if view is missing or cannot be resolved
	 * @throws Exception if there's a problem rendering the view
	 */
	// 2、DispatcherServlet 的 render 方法
	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 != null ? this.localeResolver.resolveLocale(request) : request.getLocale());
		response.setLocale(locale);

		View view;
		String viewName = mv.getViewName();
		if (viewName != null) {
			// We need to resolve the view name.
			// 根据视图名称 和 Locale 解析成 View 对象
			view = resolveViewName(viewName, 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.
			// 直接从 ModelAndView 中获取 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.isTraceEnabled()) {
			logger.trace("Rendering view [" + view + "] ");
		}
		try {
			if (mv.getStatus() != null) {
				response.setStatus(mv.getStatus().value());
			}
			// 调用 AbstractView 的 render 方法渲染视图
			view.render(mv.getModelInternal(), request, response);
		}
		catch (Exception ex) {
			if (logger.isDebugEnabled()) {
				logger.debug("Error rendering view [" + view + "]", ex);
			}
			throw ex;
		}
	}


	/**
	 * Prepares the view given the specified model, merging it with static
	 * attributes and a RequestContext attribute, if necessary.
	 * Delegates to renderMergedOutputModel for the actual rendering.
	 * @see #renderMergedOutputModel
	 */
	// 3、AbstractView 的 render 方法
	@Override
	public void render(@Nullable Map<String, ?> model, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		if (logger.isDebugEnabled()) {
			logger.debug("View " + formatViewName() +
					", model " + (model != null ? model : Collections.emptyMap()) +
					(this.staticAttributes.isEmpty() ? "" : ", static attributes " + this.staticAttributes));
		}
		
		// 合并填充数据 Model
		Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
		prepareResponse(request, response);
		// 模板方法,即调用具体的视图渲染器的 renderMergedOutputModel 方法来渲染视图
		renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
	}

整个过程不复杂,至于具体的视图渲染器是怎么来渲染视图的,这里不做源码分析了,感兴趣的可以自己分析

四、总结

SpringMVC 的核心处理逻辑在 DispatcherServlet 中,如果你对 DispatcherServlet 源码了解了,SpringMVC 的工作原理自然就理解了,在学习过程中,还是希望大家尽量 debug 调试源码,以便自己更好地理解源码意图。如有不正之处,请大家指正,谢谢

猜你喜欢

转载自blog.csdn.net/ywlmsm1224811/article/details/103250620
今日推荐