SpringMVC请求执行全流程源码解析

本文将通过源码阅读,解析请求在SpringMVC中的处理流程,包括DispatcherServlet的初始化,查找处理器,查找映射器等流程。阅读本文前最好先读一下之前写的前置文章,才能更好的理解一些全局变量是如何初始化并赋值的。可以先阅读以下文章:
SpringMVC HandlerMapping(处理器映射器)常用实现类源码详解
RequestMappingHandlerAdapter源码解析
SpringMVC自动配置类避坑及源码详解

前置概念

父子容器概念

Spring会创建一个WebApplicationContext上下文,称为父上下文(父容器) ,保存在 ServletContext中, key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值。可以使用Spring提供的工具类取出上下文对象:WebApplicationContextUtils.getWebApplicationContext(ServletContext);

DispatcherServlet是一个Servlet,可以同时配置多个,每个 DispatcherServlet有一个自己的上下文对象(WebApplicationContext),称为子上下文(子容器),子上下文可以访问父上下文中的内容,但父上下文不能访问子上下文中的内容。 它也保存在 ServletContext中,key是"org.springframework.web.servlet.FrameworkServlet.CONTEXT"+Servlet名称。当一个Request对象产生时,会把这个子上下文对象(WebApplicationContext)保存在Request对象中,key是DispatcherServlet.class.getName() + “.CONTEXT”。 可以使用工具类取出上下文对象:RequestContextUtils.getWebApplicationContext(request);

所以在Controller中注入Service和Dao对象是可以的,但是反过来是不可以的,因为Service和Dao的对象是存放在父容器中的,而Controller是在子容器中的。

springMVC核心过滤器DispatcherServlet

Servlet初始化时机是在项目启动后,第一次请求过来的时候进行初始化的,DispatcherServlet就是第一次请求过来的时候初始化的。

在springboot中核心过滤器的自动创建是由自动配置类DispatcherServletAutoConfiguration进行创建和注册的,代码如下:

//创建dispatcherServlet
@Bean(name = {"dispatcherServlet"})
public DispatcherServlet dispatcherServlet() {
	DispatcherServlet dispatcherServlet = new DispatcherServlet();
	dispatcherServlet.setDispatchOptionsRequest(this.webMvcProperties.isDispatchOptionsRequest());
	dispatcherServlet.setDispatchTraceRequest(this.webMvcProperties.isDispatchTraceRequest());
	dispatcherServlet.setThrowExceptionIfNoHandlerFound(this.webMvcProperties.isThrowExceptionIfNoHandlerFound());
	return dispatcherServlet;
}

//注册servlet
@Bean(name = {"dispatcherServletRegistration"})
@ConditionalOnBean(value = {DispatcherServlet.class},name = {"dispatcherServlet"})
public ServletRegistrationBean<DispatcherServlet> dispatcherServletRegistration(DispatcherServlet dispatcherServlet) {
	ServletRegistrationBean<DispatcherServlet> registration = new ServletRegistrationBean(dispatcherServlet, new String[]{this.serverProperties.getServlet().getServletMapping()});
	registration.setName("dispatcherServlet");
	registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup());
	if (this.multipartConfig != null) {
		registration.setMultipartConfig(this.multipartConfig);
	}
	return registration;
}

DispatcherServlet类的源码解析

初始化过程

DispatcherServlet就是第一次请求过来的时候初始化的
DispatcherServlet初始化方法,从容器中获取到接口实现类,存储在类的全局变量中。接口实现类在项目启动的时候已经注入到了容器中。

protected void initStrategies(ApplicationContext context) {
	//初始化文件上传解析器 -->MultipartResolver 接口
	initMultipartResolver(context); 
	//初始化国际化相关解析器 -->LocaleResolver 接口
	initLocaleResolver(context);
	//初始化主题样式解析器 -->ThemeResolver 接口
	initThemeResolver(context);
	//初始化处理器映射器 -->HandlerMapping 接口
	//RequestMappingHandlerMapping  SimpleUrlHandlerMapping BeanNameUrlHandlerMapping  
	initHandlerMappings(context);
	//初始化处理器适配器 -->HandlerAdapter 接口
	initHandlerAdapters(context);
	//初始化异常解析器 -->HandlerExceptionResolver 接口
	initHandlerExceptionResolvers(context);
	// RequestToViewNameTranslator接口
	initRequestToViewNameTranslator(context);
	//初始化视图解析器 --> ViewResolver 接口
	initViewResolvers(context);
	//初始化重定向参数管理器 --> FlashMapManager 接口
	initFlashMapManager(context);
}

请求处理流程

请求入口

Servlet接口规范所有的请求都是走Servlet的service方法。抽象类HttpServlet实现了该接口,再此基础上衍生出根据不同请求方式分发请求到不同的方法。如doGet doPost doPut等几个方法
在这里插入图片描述
上图中,可以看出DispatcherServlet继承了并重写了上述方法,最终又全部交个processRequest方法处理,该方法省略后部分代码如下:

protected final void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	//......省略代码
	try {
		doService(request, response);
	}catch (Exception ex) {
		throw ex;
	}finally {
		//.....省略代码
		//发布处理事件
		publishRequestHandledEvent(request, response, startTime, failureCause);
	}
}

处理请求的核心逻辑由doService方法实现,这个是交个子类实现, DispatcherServlet继承并实现了该方法。
在请求处理完成的最后,发布了一个请求被处理的事件,事件代码如下:

private void publishRequestHandledEvent(HttpServletRequest request, HttpServletResponse response,
		long startTime, @Nullable Throwable failureCause) {
	if (this.publishEvents && this.webApplicationContext != null) {
		// Whether or not we succeeded, publish an event.
		long processingTime = System.currentTimeMillis() - startTime;
		this.webApplicationContext.publishEvent(
				new ServletRequestHandledEvent(this,
						request.getRequestURI(), request.getRemoteAddr(),
						request.getMethod(), getServletConfig().getServletName(),
						WebUtils.getSessionId(request), getUsernameForRequest(request),
						processingTime, failureCause, response.getStatus()));
	}
}

该事件收集了请求的所有信息,应用层面可以通过监听该事件进行对不同接口请求的信息统计,然后根据统计信息做一下接口并发限制或者降级逻辑。

DispatcherServlet处理方法doService

这个方法进行简单的处理,将请求绑定一些相关组件进行资源处理和解析。

protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
	
	//判断是否是include的页面请求,并将include的请求相关参数复制一份进行存储
	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));
			}
		}
	}
	//这里绑定的key都关联到了对应的Servlet,因为每一个Servlet都需要一个上下文容器
	//将请求绑定springMVC上下文容器,也就是所谓的子容器
	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());
	
	//flushMap解决重定向传参问题
	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(request, response);
	}finally {
		if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
			if (attributesSnapshot != null) {
				restoreAttributesAfterInclude(request, attributesSnapshot);
			}
		}
	}
}

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 {
			//通过contentType判断是不是文件上传的请求,然后将请求转换成StandardMultipartHttpServletRequest
			processedRequest = checkMultipart(request);
			//通过判断request是否被转换过,修改是否文件上传的请求标记
			multipartRequestParsed = (processedRequest != request);

			//获取当前请求对应的处理器执行链
			mappedHandler = getHandler(processedRequest);
			if (mappedHandler == null) {
				noHandlerFound(processedRequest, response);
				return;
			}

			//获取处理器适配器(三种类型中的一种)
			HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

			//处理last-modified请求头(如果处理器支持)
			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;
			}

			//调用处理器(controller)的方法
			mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
			
			//如果异步任务已经开始,则直接返回
			if (asyncManager.isConcurrentHandlingStarted()) {
				return;
			}
			//使用默认的视图名称
			applyDefaultViewName(processedRequest, mv);
			//调用拦截器的postHandle方法
			mappedHandler.applyPostHandle(processedRequest, response, mv);
			
		}catch (Exception ex) {
			dispatchException = ex;
		}
		//处理分发结果:例如处理异常,清除资源,最后调用拦截器的afterCompletion方法
		processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		
	}catch (Exception ex) {
		//回调拦截器的afterCompletion方法
		triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
	}finally {
		//判断是否是异步请求方式并且已经请求已经开始处理了
		if (asyncManager.isConcurrentHandlingStarted()) {
			//调用异步处理拦截器的afterConcurrentHandlingStarted方法,替换拦截器的postHandle和afterCompletion方法
			if (mappedHandler != null) {
				mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
			}
		}else {
			//multipart文件下载类请求清除资源
			if (multipartRequestParsed) {
				cleanupMultipart(processedRequest);
			}
		}
	}
}
获取处理器执行链
1. 获取处理器映射器,用于获取处理器执行链
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
	//该类实例化的时候收集了所有的处理器映射器,可查看构造方法
	if (this.handlerMappings != null) {
		for (HandlerMapping hm : this.handlerMappings) {
			//通过处理器映射器构建并拿到对应的处理器执行链
			HandlerExecutionChain handler = hm.getHandler(request);
			if (handler != null) {
				return handler;
			}
		}
	}
	return null;
}
2.通过映射器获取处理器和拦截器封装成处理器执行链

AbstractHandlerMapping的getHandler方法

@Nullable
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {

	//从request中拿到请求的uri-->从MappingRegistry.urlLookup中获取到RequestMappingInfo
	//-->再从从MappingRegistry.mappingLookup 拿到HandlerMethod进行匹配后并返回
	Object handler = getHandlerInternal(request);   //这里会执行RequestCondition.getMatchingCondition方法
	
	//找不到则使用默认的
	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 (CorsUtils.isCorsRequest(request)) {
		CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request);
		CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
		CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
		executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
	}
	return executionChain;
}


protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
	//将handler封装到执行器链
	HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
			(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

	String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
	for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
		if (interceptor instanceof MappedInterceptor) {
			MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
			if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
				chain.addInterceptor(mappedInterceptor.getInterceptor());
			}
		}
		else {
			chain.addInterceptor(interceptor);
		}
	}
	return chain;
}
3.获取处理器的流程

getHandlerInternal(request)获取处理器的细节方法,主要思路就是:

  1. 从request中拿到请求的uri–>从MappingRegistry.urlLookup中获取到RequestMappingInfo
  2. 再从从MappingRegistry.mappingLookup 拿到HandlerMethod进行匹配后并返回

MappingRegistry类封装了所有处理器的信息,不清楚的请阅读我这篇文章:
SpringMVC HandlerMapping(处理器映射器)常用实现类源码详解中的RequestMappingHandlerMapping初始化过程源码解析一节。

源码流程如下:

3.1 获取请求uri
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
	//从请求中解析获取到请求的uri,这个uri包括项目路径和servlet的path
	String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
	if (logger.isDebugEnabled()) {
		logger.debug("Looking up handler method for path " + lookupPath);
	}
	this.mappingRegistry.acquireReadLock();
	try {
		//通过请求参数和路径查找处理器
		HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
		//....省略日志代码
		//复制处理器信息,构建新的返回(如果拿到是Bean名字,先从容器中获取再复制)
		return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
	}
	finally {
		this.mappingRegistry.releaseReadLock();
	}
}
3.2 通过请求参数和路径查找处理器
@Nullable
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
	List<Match> matches = new ArrayList<>();
	//获取同一个uri映射的接口方法信息RequestMappingInfo
	List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
	if (directPathMatches != null) {
		//变量拿到的集合信息,重新封装到一个新的RequestMappingInfo对象,存到到matches中
		//这里调用了自定义的RequestCondition接口getMatchingCondition方法
		addMatchingMappings(directPathMatches, matches, request);
	}
	if (matches.isEmpty()) {
		//遍历所有的处理器映射器获取匹配的处理器方法
		addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
	}

	if (!matches.isEmpty()) {
		//构建比较器
		Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
		matches.sort(comparator);
		if (logger.isTraceEnabled()) {
			logger.trace("...." + matches);
		}
		Match bestMatch = matches.get(0);
		//如果找到多个处理器方法(自定义才可能出现的情况)
		if (matches.size() > 1) {
			if (CorsUtils.isPreFlightRequest(request)) {
				return PREFLIGHT_AMBIGUOUS_MATCH;
			}
			//只是比较前两个
			Match secondBestMatch = matches.get(1);
			//调用自定义的RequestCondition接口compareTo方法
			if (comparator.compare(bestMatch, secondBestMatch) == 0) {
				Method m1 = bestMatch.handlerMethod.getMethod();
				Method m2 = secondBestMatch.handlerMethod.getMethod();
				throw new IllegalStateException("....." );
			}
		}
		//将请求路径封存放到request域对象中
		handleMatch(bestMatch.mapping, lookupPath, request);
		//返回处理器
		return bestMatch.handlerMethod;
	}
	else {
		return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
	}
}
获取处理器适配器
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
	if (this.handlerAdapters != null) {
		for (HandlerAdapter ha : this.handlerAdapters) {
			if (logger.isTraceEnabled()) {
				logger.trace(".....");
			}
			//获取处理器适配器(三种类型中的一种)
			if (ha.supports(handler)) {
				return ha;
			}
		}
	}
	throw new ServletException(".....");
}

调用处理器(Controller)方法

跟踪handle方法,可以发现,调用处理器方法的逻辑最终实现是在处理器适配器RequestMappingHandlerAdapter的handleInternal方法中实现的。查看该方法代码如下:

@Override
protected ModelAndView handleInternal(HttpServletRequest request,
		HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

	ModelAndView mav;
	//检查请求是否符合要求
	checkRequest(request);

	//判断执行处理器方法是否需要在session上窜行,默认否
	if (this.synchronizeOnSession) {
		HttpSession session = request.getSession(false);
		if (session != null) {
			//使用互斥锁
			Object mutex = WebUtils.getSessionMutex(session);
			synchronized (mutex) {
				mav = invokeHandlerMethod(request, response, handlerMethod);
			}
		}else {
			//没有session,不需要互斥锁,执行处理器方法
			mav = invokeHandlerMethod(request, response, handlerMethod);
		}
	}else {
		//执行处理器方法
		mav = invokeHandlerMethod(request, response, handlerMethod);
	}
	
	//判断处理Cache-Control请求头,根据条件设置响应请求头
	if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
		if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
			applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
		}else {
			//准备Cache-Control请求头,设置缓存时间
			prepareResponse(response);
		}
	}

	return mav;
}
反射调用Controller方法
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
		HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

	ServletWebRequest webRequest = new ServletWebRequest(request, response);
	try {
		//将@InitBinder注解标记方法封装到工厂类中
		WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
		
		//将@ModelAttribute注解标记的方法封装到工厂类中
		ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
		
		//创建调用方法对象,并封装对应的解析类
		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);
		
		//创建并设置视图和模型相关参数属性
		ModelAndViewContainer mavContainer = new ModelAndViewContainer();
		mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
		modelFactory.initModel(webRequest, mavContainer, invocableMethod);
		mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
		
		//处理异步的相关参数和组件
		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();
			
			invocableMethod = invocableMethod.wrapConcurrentResult(result);
		}
		//反射调用处理器方法
		invocableMethod.invokeAndHandle(webRequest, mavContainer);
		if (asyncManager.isConcurrentHandlingStarted()) {
			return null;
		}

		return getModelAndView(mavContainer, modelFactory, webRequest);
	}
	finally {
		webRequest.requestCompleted();
	}
}

//反射调用处理器方法
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
		Object... providedArgs) throws Exception {
	
	//调用方法获取返回值
	Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
	setResponseStatus(webRequest);

	if (returnValue == null) {
		if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
			mavContainer.setRequestHandled(true);
			return;
		}
	}
	else if (StringUtils.hasText(getResponseStatusReason())) {
		mavContainer.setRequestHandled(true);
		return;
	}

	mavContainer.setRequestHandled(false);
	Assert.state(this.returnValueHandlers != null, "No return value handlers");
	try {
		//选择一个匹配的返回值处理器HandlerMethodReturnValueHandler处理返回值,写回响应
		//调用handleReturnValue方法,默认自定义的组件排在系统组件之后
		this.returnValueHandlers.handleReturnValue(
				returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
	}catch (Exception ex) {
		
		throw ex;
	}
}


@Nullable
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
		Object... providedArgs) throws Exception {
	//调用参数解析器解析方法入参
	Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
	if (logger.isTraceEnabled()) {
		logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
				"' with arguments " + Arrays.toString(args));
	}
	//反射调用controller方法
	Object returnValue = doInvoke(args);
	if (logger.isTraceEnabled()) {
		logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
				"] returned [" + returnValue + "]");
	}
	return returnValue;
}

/**
 * 对当前方法入参进行解析
 */
private Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
		Object... providedArgs) throws Exception {
	//获取调用Controller方法的所有参数列表
	MethodParameter[] parameters = getMethodParameters();
	Object[] args = new Object[parameters.length];
	
	//循环对参数进行解析赋值和校验
	for (int i = 0; i < parameters.length; i++) {
		MethodParameter parameter = parameters[i];
		parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
		//从一系列提供的参数中解析,视图相关
		args[i] = resolveProvidedArgument(parameter, providedArgs);
		if (args[i] != null) {
			continue;
		}
		//循环遍历所有的参数解析器,判断是否有支持该参数解析的方式
		//调用扩展接口HandlerMethodArgumentResolver.supportsParameter方法
		if (this.argumentResolvers.supportsParameter(parameter)) {
			try {
				//获取扩展接口HandlerMethodArgumentResolver对应实例,调用resolveArgument方法解析参数
				args[i] = this.argumentResolvers.resolveArgument(
						parameter, mavContainer, request, this.dataBinderFactory);
				continue;
			}catch (Exception ex) {
				throw ex;
			}
		}
		if (args[i] == null) {
			throw new IllegalStateException("....");
		}
	}
	return args;
}

总结

调用逻辑总体上是,获取并组装处理器信息,然后获取适配器,通过适配器调用参数解析器组装入参,之后反射调用处理器的方法,最后通过返回值处理器,视图解析器等组件处理响应。

现在流行restful接口,前后端分离形式,点击阅读这篇文章关于@RequestBody @ResponseBody 注解处理的类RequestResponseBodyMethodProcessor 。同时负责参数解析和返回值解析。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值