springmvc源码笔记-HandlerMethodReturnValueHandler

返回值解析器

用于对controller的返回值进行二次处理


结构

// 返回值解析器
public interface HandlerMethodReturnValueHandler {

	// 判断 HandlerMethodReturnValueHandler 是否支持 MethodParameter
	boolean supportsReturnType(MethodParameter returnType);

	// 处理给定的返回值
	void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;
}

调用

完整调用链

DispatcherServlet#doDispatch()
AbstractHandlerMethodAdapter#handle()
RequestMappingHandlerAdapter#handleInternal()
// 在这里会创建ServletInvocableHandlerMethod,此时已经将controller的函数(HandlerMethod)的参数注入到InvocableHandlerMethod(类变量)中
RequestMappingHandlerAdapter#invokeHandlerMethod()
// 在这里,invokeForRequest通过反射的方式调用controller中的方法并返回returnValue
ServletInvocableHandlerMethod#invokeAndHandle()
// 处理返回值方法
HandlerMethodReturnValueHandlerComposite#handleReturnValue
// 获取返回值处理器
HandlerMethodReturnValueHandlerComposite#selectHandler
// 处理返回值
HandlerMethodReturnValueHandler#handleReturnValue

RequestMappingHandlerAdapter#invokeHandlerMethod()中调用了controller,并得到了返回值

public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {
	// 调用handler(controller+method),得到返回值
	Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
	setResponseStatus(webRequest);

	。。。。。。
	try {
		// 处理返回值方法
		// returnValueHandlers是HandlerMethodReturnValueHandlerComposite类
		this.returnValueHandlers.handleReturnValue(
				returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
	}
	catch (Exception ex) {
		if (logger.isTraceEnabled()) {
			logger.trace(formatErrorForReturnValue(returnValue), ex);
		}
		throw ex;
	}
}

接下来,就轮到HandlerMethodReturnValueHandlerComposite表演了

// 处理返回值
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
	// 查找处理器
	HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
	if (handler == null) {
		throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
	}
	// 此处handler就是HandlerMethodReturnValueHandler的实现类
	// HandlerMethodReturnValueHandler#handleReturnValue处理返回值
	handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
}

// 查找处理器
private HandlerMethodReturnValueHandler selectHandler(@Nullable Object value, MethodParameter returnType) {
		boolean isAsyncValue = isAsyncReturnValue(value, returnType);
	// returnValueHandlers就是HandlerMethodReturnValueHandler的实现类集合,默认有15个实现类
	// 注意:returnValueHandlers是有顺序的
	for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) {
		if (isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler)) {
			continue;
		}
		// 使用supportsReturnType方法判断该处理器是否支持解析当前返回值
		if (handler.supportsReturnType(returnType)) {
			return handler;
		}
	}
	return null;
}

执行顺序

HandlerMethodReturnValueHandler的调用是有执行顺序的,如果自定义的HandlerMethodReturnValueHandler没有被触发,请检查是否被其他handler抢先了

处理器处理类型处理种类
ModelAndViewMethodReturnValueHandlerModelAndView一种类型
ModelMethodProcessorModel一种类型
ViewMethodReturnValueHandlerView一种类型
ResponseBodyEmitterReturnValueHandlerResponseEntity一种类型
StreamingResponseBodyReturnValueHandlerResponseEntity一种类型
HttpHeadersReturnValueHandlerHttpHeaders一种类型
CallableMethodReturnValueHandlerCallable一种类型
DeferredResultMethodReturnValueHandlerDeferredResult、ListenableFuture、CompletionStage一种类型
AsyncTaskMethodReturnValueHandlerWebAsyncTask一种类型
ModelAttributeMethodProcessor@ModelAttribute(require=false)针对注解
RequestResponseBodyMethodProcessor@ResponseBody针对注解
ViewNameMethodReturnValueHandlervoid、CharSequence(V4.2)多种类型
MapMethodProcessorMap多种类型
自定义返回值处理器自定义
ServletModelAttributeMethodProcessor兜底方法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值