springmvc组件HandlerAdapter源码分析-RequestMappingHandlerAdapter

  1.springmvc中RequestMappingHandlerAdapter继承体系

2.概述

首先,RequestMappingHandlerAdapter实现了InitializingBean接口。

bean初始化时会调用afterPropertiesSet方法来处理加了ControllerAdvice注解的类

加载HandlerMethodArgumentResolver参数解析器处理参数

加载处理InitBinder的HandlerMethodArgumentResolver参数解析器

加载HandlerMethodReturnValueHandler返回值处理程序处理返回值。

之后就是重写了HandlerAdapter的supportsInternal方法来判断次适配器是否支持处理HandlerMethod类型的处理器,这里是支持。

重写了HandlerAdapter的handle方法来处理请求

3.RequestMappingHandlerMapping整个代码用工具翻译后的

https://blog.csdn.net/qq_39482039/article/details/120257541

4.初始化流程分析

RequestMappingHandlerAdapter实现了InitializingBean接口,bean初始化时会调用afterPropertiesSet方法。

@Override
	public void afterPropertiesSet() {
		// 首先这样做,它可能会添加 ResponseBody 建议 bean
		//加载加了ControllerAdvice注解的类
		initControllerAdviceCache();
		//参数解析为空,加载默认的参数解析类
		if (this.argumentResolvers == null) {
			List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
			this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
		}
		//参数解析为空,加载默认的初始化参数绑定类
		if (this.initBinderArgumentResolvers == null) {
			List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
			this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
		}
		//如果返回值处理属性为空,加载默认的返回值处理类
		if (this.returnValueHandlers == null) {
			List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
			this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
		}
	}

 initControllerAdviceCache方法

 从web上下文中查找加了ControllerAdvice注解的bean

 查找bean中没有加RequestMapping注解,加了ModelAttribute注解的方法,设置到属性   modelAttributeAdviceCache

 查找加了InitBinder的方法,设置到属性initBinderAdviceCache

 查找父类是RequestBodyAdvice或ResponseBodyAdvice的类,设置到属性   requestResponseBodyAdvice

private void initControllerAdviceCache() {
		if (getApplicationContext() == null) {
			return;
		}
		//处理加了ControllerAdvice注解的类
		List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());

		List<Object> requestResponseBodyAdviceBeans = new ArrayList<>();

		for (ControllerAdviceBean adviceBean : adviceBeans) {
			Class<?> beanType = adviceBean.getBeanType();
			if (beanType == null) {
				throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
			}
			//查找bean中没有加RequestMapping注解,加了ModelAttribute注解的方法
			Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
			if (!attrMethods.isEmpty()) {
				//缓存加了ModelAttribute方法
				this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
			}
			//查找bean中加了InitBinder注解的方法
			Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
			if (!binderMethods.isEmpty()) {
				//缓存ModelAttribute注解的方法
				this.initBinderAdviceCache.put(adviceBean, binderMethods);
			}
			//bean类型的父类是RequestBodyAdvice或者ResponseBodyAdvice添加进requestResponseBodyAdviceBeans里
			if (RequestBodyAdvice.class.isAssignableFrom(beanType) || ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
				requestResponseBodyAdviceBeans.add(adviceBean);
			}
		}
		//设置requestResponseBodyAdviceBeans到requestResponseBodyAdvice属性
		if (!requestResponseBodyAdviceBeans.isEmpty()) {
			this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
		}

		if (logger.isDebugEnabled()) {
			int modelSize = this.modelAttributeAdviceCache.size();
			int binderSize = this.initBinderAdviceCache.size();
			int reqCount = getBodyAdviceCount(RequestBodyAdvice.class);
			int resCount = getBodyAdviceCount(ResponseBodyAdvice.class);
			if (modelSize == 0 && binderSize == 0 && reqCount == 0 && resCount == 0) {
				logger.debug("ControllerAdvice beans: none");
			} else {
				logger.debug("ControllerAdvice beans: " + modelSize + " @ModelAttribute, " + binderSize +
						" @InitBinder, " + reqCount + " RequestBodyAdvice, " + resCount + " ResponseBodyAdvice");
			}
		}
	}
getDefaultArgumentResolvers方法获取默认的参数解析器
/**
	 * 返回要使用的参数解析器列表,包括内置解析器
	 * 和通过 {@link #setCustomArgumentResolvers} 提供的自定义解析器。
	 */
	private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
		List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();

		// 基于注释的参数解析
		//解析加了RequestParam注解的参数
		resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
		//解析加了RequestParamMap注解的参数
		resolvers.add(new RequestParamMapMethodArgumentResolver());
		//解析加了PathVariable注解的参数
		resolvers.add(new PathVariableMethodArgumentResolver());
		//解析加了PathVariable注解的map
		resolvers.add(new PathVariableMapMethodArgumentResolver());
		//解析加了MatrixVariable注解的参数
		resolvers.add(new MatrixVariableMethodArgumentResolver());
		//解析加了MatrixVariable注解的map参数
		resolvers.add(new MatrixVariableMapMethodArgumentResolver());
		//
		resolvers.add(new ServletModelAttributeMethodProcessor(false));
		//解析加了RequestBody或加了ResponseBody注解的参数或方法
		resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
		//解析RequestPart注解的参数
		resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
		//解析加了RequestHeader注解的参数
		resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
		//解析加了RequestHeader注解的map参数
		resolvers.add(new RequestHeaderMapMethodArgumentResolver());
		//解析HttpServletRequest的cookie值
		resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
		//解析加了Value注解的参数
		resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
		//解析加了SessionAttribute的参数
		resolvers.add(new SessionAttributeMethodArgumentResolver());
		//解析加了RequestAttribute的参数
		resolvers.add(new RequestAttributeMethodArgumentResolver());

		// 基于类型的参数解析
		//解析 servlet 支持的与请求相关的方法参数
		resolvers.add(new ServletRequestMethodArgumentResolver());
		//解析 servlet 支持的响应相关方法参数
		resolvers.add(new ServletResponseMethodArgumentResolver());
		//解析 {@link HttpEntity} 和 {@link RequestEntity} 方法参数值
		//并且还处理 {@link HttpEntity} 和 {@link ResponseEntity} 返回值。
		resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
		//解析加了RedirectAttributes注解的参数
		resolvers.add(new RedirectAttributesMethodArgumentResolver());
		//解析model参数,并处理Model返回值
		resolvers.add(new ModelMethodProcessor());
		//解析map参数并处理map返回值
		resolvers.add(new MapMethodProcessor());
		//解析错误返回信息,BindingResult
		resolvers.add(new ErrorsMethodArgumentResolver());
		//解析SessionStatus参数
		resolvers.add(new SessionStatusMethodArgumentResolver());
		//解析UriComponentsBuilder类型的参数
		resolvers.add(new UriComponentsBuilderMethodArgumentResolver());

		// 自定义参数解析
		if (getCustomArgumentResolvers() != null) {
			resolvers.addAll(getCustomArgumentResolvers());
		}

		//包罗万象
		resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
		resolvers.add(new ServletModelAttributeMethodProcessor(true));

		return resolvers;
	}
getDefaultInitBinderArgumentResolvers方法用于加载InitBinder的参数解析器
/**
	 * 返回用于 {@code @InitBinder} 的参数解析器列表
	 * 包括内置和自定义解析器的方法。
	 */
	private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() {
		List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();

		// 基于注释的参数解析
		resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
		resolvers.add(new RequestParamMapMethodArgumentResolver());
		resolvers.add(new PathVariableMethodArgumentResolver());
		resolvers.add(new PathVariableMapMethodArgumentResolver());
		resolvers.add(new MatrixVariableMethodArgumentResolver());
		resolvers.add(new MatrixVariableMapMethodArgumentResolver());
		resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
		resolvers.add(new SessionAttributeMethodArgumentResolver());
		resolvers.add(new RequestAttributeMethodArgumentResolver());

		// 基于类型的参数解析
		resolvers.add(new ServletRequestMethodArgumentResolver());
		resolvers.add(new ServletResponseMethodArgumentResolver());

		//自定义参数
		if (getCustomArgumentResolvers() != null) {
			resolvers.addAll(getCustomArgumentResolvers());
		}

		// 包罗万象
		resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));

		return resolvers;
	}
getDefaultReturnValueHandlers方法加载默认的返回值处理器
/**
	 * 返回要使用的返回值处理程序列表,包括内置和
	 * 通过 {@link #setReturnValueHandlers} 提供的自定义处理程序。
	 */
	private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
		List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>();

		// 单一用途的返回值类型
		//加载返回值类型是ModelAndView的处理器
		handlers.add(new ModelAndViewMethodReturnValueHandler());
		//加载model类型的返回值的处理器
		handlers.add(new ModelMethodProcessor());
		//加载返回值类型是View的处理器
		handlers.add(new ViewMethodReturnValueHandler());
		//加载ResponseBodyEmitter返回值类型的处理器
		handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),
				this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));
		//加载StreamingResponseBody类型的处理器
		handlers.add(new StreamingResponseBodyReturnValueHandler());
		//加载处理HttpEntity和ResponseEntity返回值的处理器
		handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),
				this.contentNegotiationManager, this.requestResponseBodyAdvice));
		//加载HttpHeaders返回值的处理器
		handlers.add(new HttpHeadersReturnValueHandler());
		//加载Callable类型返回值的处理器
		handlers.add(new CallableMethodReturnValueHandler());
		//加载DeferredResult类型返回值的处理器
		handlers.add(new DeferredResultMethodReturnValueHandler());
		//处理WebAsyncTask返回值类型的处理器
		handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));

		// 基于注解的返回值类型
		//解析加了ModelAttribute注解的处理器
		handlers.add(new ModelAttributeMethodProcessor(false));
		//解析加了ResponseBody的处理器
		handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),
				this.contentNegotiationManager, this.requestResponseBodyAdvice));

		// 多用途返回值类型
		//加载处理类型是void或String处理器
		handlers.add(new ViewNameMethodReturnValueHandler());
		//加载返回值是map的处理器
		handlers.add(new MapMethodProcessor());

		// 自定义返回值类型
		if (getCustomReturnValueHandlers() != null) {
			handlers.addAll(getCustomReturnValueHandlers());
		}

		//包罗万象
		if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {
			handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));
		} else {
			handlers.add(new ModelAttributeMethodProcessor(true));
		}

		return handlers;
	}

5.请求处理流程分析

 覆盖了父类的supportsInternal抽象方法,支持处理HandlerMethod

/**
	 * 始终返回 {@code true},因为任何方法参数和返回值
	 * 类型会以某种方式进行处理。无法识别方法参数
	 * 被任何 HandlerMethodArgumentResolver 解释为请求参数
	 * 如果它是简单类型,否则作为模型属性。一个返回值
	 * 不被任何 HandlerMethodReturnValueHandler 识别的将被解释
	 * 作为模型属性。
	 */
	@Override
	protected boolean supportsInternal(HandlerMethod handlerMethod) {
		return true;
	}

 重新了父类的handleInternal抽象方法处理请求

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

		ModelAndView mav;
		//检查是否支持此请求方法
		checkRequest(request);

		// 如果需要,在同步块中执行 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 {
				//没有可用的 HttpSession -> 不需要互斥量
				mav = invokeHandlerMethod(request, response, handlerMethod);
			}
		} else {
			//根本不需要会话同步...
			mav = invokeHandlerMethod(request, response, handlerMethod);
		}
		//返回值中有Cache-Control的header参数
		if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
			//session属性处理器处理
			if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
				applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
			} else {
				prepareResponse(response);
			}
		}

		return mav;
	}

主要方法invokeHandlerMethod,调用加了RequestMapping注解的方法,执行对应的请求逻辑,返回ModelAndView

/**
	 * 调用 {@link RequestMapping} 处理程序方法准备 {@link ModelAndView}
	 * 如果需要视图分辨率。
	 *
	 * @see #createInvocableHandlerMethod(HandlerMethod)
	 * @since 4.2
	 */
	@Nullable
	protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
											   HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

		//创建ServletWebRequest
		ServletWebRequest webRequest = new ServletWebRequest(request, response);
		try {
			//获取默认的处理WebDataBinder的工厂
			WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
			//获取处理model的工厂
			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);
			}
			//设置处理WebDataBinder的工厂
			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();
				LogFormatUtils.traceDebug(logger, traceOn -> {
					String formatted = LogFormatUtils.formatValue(result, !traceOn);
					return "Resume with async result [" + formatted + "]";
				});
				invocableMethod = invocableMethod.wrapConcurrentResult(result);
			}
			//执行请求方法处理
			invocableMethod.invokeAndHandle(webRequest, mavContainer);
			if (asyncManager.isConcurrentHandlingStarted()) {
				return null;
			}
			//获取ModelAndView
			return getModelAndView(mavContainer, modelFactory, webRequest);
		} finally {
			webRequest.requestCompleted();
		}
	}
invokeAndHandle方法,执行处理方法并处理返回值
/**
	 * 在给定请求的上下文中解析其参数值后调用该方法。
	 * <p>参数值通常通过
	 * {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolver}。
	 * {@code providedArgs}参数可以提供直接使用的参数值,
	 * 也就是说,没有辩论决议。提供的参数值示例包括
	 * {@link WebDataBinder}、{@link SessionStatus}或引发的异常实例。
	 * 在参数解析程序之前检查提供的参数值。
	 * <p>委托给{@link#getMethodArgumentValues}并使用
	 *
	 * 已解决的争论。
	 * @param request the current request
	 * @param mavContainer the ModelAndViewContainer for this request
	 * @param providedArgs "given" arguments matched by type, not resolved
	 * @return the raw value returned by the invoked method
	 * @throws Exception raised if no suitable argument resolver can be found,
	 * or if the method raised an exception
	 * @see #getMethodArgumentValues
	 * @see #doInvoke
	 */
	@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));
		}
		return doInvoke(args);
	}
getMethodArgumentValues方法处理参数解析
/**
	 * 获取当前请求的方法参数值,检查提供的
	 * 参数值,并返回到配置的参数解析程序。
	 * <p>生成的数组将被传递到{@link#doInvoke}。
	 * @since 5.1.2
	 */
	protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {
		//获取方法参数
		MethodParameter[] parameters = getMethodParameters();
		if (ObjectUtils.isEmpty(parameters)) {
			return EMPTY_ARGS;
		}

		Object[] args = new Object[parameters.length];
		for (int i = 0; i < parameters.length; i++) {
			MethodParameter parameter = parameters[i];
			parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
			args[i] = findProvidedArgument(parameter, providedArgs);
			if (args[i] != null) {
				continue;
			}
			if (!this.resolvers.supportsParameter(parameter)) {
				throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
			}
			try {
				args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
			}
			catch (Exception ex) {
				// Leave stack trace for later, exception may actually be resolved and handled...
				if (logger.isDebugEnabled()) {
					String exMsg = ex.getMessage();
					if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {
						logger.debug(formatArgumentError(parameter, exMsg));
					}
				}
				throw ex;
			}
		}
		return args;
	}

反射处理方法

/**
	 * 使用给定的参数值调用处理程序方法。
	 */
	@Nullable
	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(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);
			}
		}
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LouD_dm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值