SpringMvc源码分析(四) 请求执行过程之执行MethodHandler

   在上文SpringMvc源码分析(三)中我们分析了DispatcherServlet类中的doDispatcher方法,

并通过分析方法1和方法2了解了请求执行时是怎么获取MethodHandler链的,本文接上文继续分析方法3、方法4和方法5了解MethodHandler是如何执行的。

在该源码中需要关注以下代码

1.getHandler(processedRequest)   获取处理器链的方法

2.getHandlerAdapter(mappedHandler.getHandler())  获取处理器链适配器

3.mappedHandler.applyPreHandle(processedRequest, response) 请求前预处理

4.ha.handle(processedRequest, response, mappedHandler.getHandler())调用适配器的处理方法

5.mappedHandler.applyPostHandle(processedRequest, response, mv)请求执行后处理

6.processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException)

1.方法3 请求前预处理

分析mappedHandler.applyPreHandle(processedRequest, response)源码,该方法是HandlerExecutionChain类中的applyPreHandle方法。

该方法中渠道了处理器链中即HandlerExecutionChain对象的interceptors属性,该属性赋值的interceptorList属性是拦截器集合是在SpringMvc源码分析(三)中的getHandler方法赋值的。

 

	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)) {
                    //如果preHandle方法返回的是false直接调用拦截器里的afterCompletion方法
					triggerAfterCompletion(request, response, null);
					return false;
				}
				this.interceptorIndex = i;
			}
		}
		return true;
	}

2.方法四:调用适配器的处理方法

   ha.handle(processedRequest, response, mappedHandler.getHandler())方法在上文中分析到ha是RequestMappingHandlerAdapter类型的对象。但是该类中没有handle方法。

   观察该类的继承实现树,发现handle方法实际调用的是AbstractHandlerMethodAdapter适配器中的handle方法。

 

    在handle方法的源码中发现其调用的hanleInternal方法调用的是RequestMappingHandlerAdapter类中的hanleInternal方法。

	public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		return handleInternal(request, response, (HandlerMethod) handler);
	}
protected ModelAndView handleInternal(HttpServletRequest request,
			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

		ModelAndView mav;
        //请求信息校验包括方法和session校验
		checkRequest(request);
        // session 是非线程安全的,如果需要保证用户能够在多次请求中正确的访问同一个 session ,
        // 就要将 synchronizeOnSession 设置为 TRUE,一般请求都设置为false 
		// Execute invokeHandlerMethod in synchronized block if required.
		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...
			mav = invokeHandlerMethod(request, response, handlerMethod);
		}

		if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
			if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
				applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
			}
			else {
				prepareResponse(response);
			}
		}

		return mav;
	}

 在上面的源码中我们发现处理器的执行方法

mav = invokeHandlerMethod(request, response, handlerMethod)

	protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
        //包装请求的request和response    
		ServletWebRequest webRequest = new ServletWebRequest(request, response);
		try {
            //获取@InitBinder 注解的方法
            //包含当前controller与 @ControllerAdvice 标注的类里的 @InitBinder 注解的方法
			WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
            //获取 @ModelAttribute 注解的方法,
            //包含当前controller与 @ControllerAdvice 标注的类里的 @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);
            //创建ModelAndView的容器
			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();
				if (logger.isDebugEnabled()) {
					logger.debug("Found concurrent result value [" + result + "]");
				}
				invocableMethod = invocableMethod.wrapConcurrentResult(result);
			}
            //重点关注此处,执行Controller中的方法
			invocableMethod.invokeAndHandle(webRequest, mavContainer);
			if (asyncManager.isConcurrentHandlingStarted()) {
				return null;
			}
            //处理返回结果
【
			return getModelAndView(mavContainer, modelFactory, webRequest);
		}
		finally {
			webRequest.requestCompleted();
		}
	}

关注invokeAndHandle方法

	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 {
            //处理返回值
			this.returnValueHandlers.handleReturnValue(
					returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
		}
		catch (Exception ex) {
			if (logger.isTraceEnabled()) {
				logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);
			}
			throw ex;
		}
	}

 关注调用的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("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
					"' with arguments " + Arrays.toString(args));
		}
        //调用反射方法
		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 {
        //获取api调用方法参数
		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;
			}
            //判断是否有参数解析器支持当前的参数
			if (this.argumentResolvers.supportsParameter(parameter)) {
				try {
                    //解析参数
					args[i] = this.argumentResolvers.resolveArgument(
							parameter, mavContainer, request, this.dataBinderFactory);
					continue;
				}
				catch (Exception ex) {
					if (logger.isDebugEnabled()) {
						logger.debug(getArgumentResolutionErrorMessage("Failed to resolve", i), ex);
					}
					throw ex;
				}
			}
			if (args[i] == null) {
				throw new IllegalStateException("Could not resolve method parameter at index " +
						parameter.getParameterIndex() + " in " + parameter.getExecutable().toGenericString() +
						": " + getArgumentResolutionErrorMessage("No suitable resolver for", i));
			}
		}
		return args;
	}

 

 

 可以看到SpringMvc为我们提供了大量的参数解析器,供我们进行选择调用。

 在下面的源码中看到了请求真正执行的方法doInvoke通过method.invoke反射的方式调用了请求。

	protected Object doInvoke(Object... args) throws Exception {
		ReflectionUtils.makeAccessible(getBridgedMethod());
		try {
			return getBridgedMethod().invoke(getBean(), args);
		}
		catch (IllegalArgumentException ex) {
			assertTargetBean(getBridgedMethod(), getBean(), args);
			String text = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument");
			throw new IllegalStateException(getInvocationErrorMessage(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 {
				String text = getInvocationErrorMessage("Failed to invoke handler method", args);
				throw new IllegalStateException(text, targetException);
			}
		}
	}

 回到invokeAndHandle方法,继续分析其中的返回值处理器对返回值的处理逻辑,返回值的处理实在this.returnValueHandlers.handleReturnValue( returnValue, getReturnValueType(returnValue), mavContainer, webRequest) ,以下是spring提供的返回值处理器,handleReturnValue方法会选取支持的处理器并对返回值做处理。

   继续回到

     继续回到RequestMappingHandlerAdapter类中的invokeHandlerMethod方法,在分析完其中的invocableMethod.invokeAndHandle(webRequest, mavContainer)方法后,继续分析invokeHandlerMethod方法中调用的getModelAndView方法。在RequestMappingHandlerAdapter类中的getModelAndView方法主要作用是生成视图。

	@Nullable
	private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
			ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {

		modelFactory.updateModel(webRequest, mavContainer);
		if (mavContainer.isRequestHandled()) {
			return null;
		}
		ModelMap model = mavContainer.getModel();
        //创建视图对象
		ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
		if (!mavContainer.isViewReference()) {
			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);
			}
		}
		return mav;
	}

 3.方法五 请求执行后处理

mappedHandler.applyPostHandle(processedRequest, response, mv)请求执行后处理

在DispatcherServlet类中的调用的mappedHandler.applyPostHandle(processedRequest, response, mv)逻辑中,mappedHandler是HandlerExecutionChain类型的对象调用的是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];
                //调用拦截器的后置处理方法
				interceptor.postHandle(request, response, this.handler, mv);
			}
		}
	}

4.总结

        本文主要讲述了以下几点

1.请求前预处理

        1获取拦截器列表,执行拦截器中的preHandle方法

2.执行请求

       1通过反射的方式执行HandlerMethod封装的方法并返回视图  

3.请求后

        1获取拦截器列表,执行拦截器中的postHandle方法

   

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值