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搶先了

處理器 處理類型 處理種類
ModelAndViewMethodReturnValueHandler ModelAndView 一種類型
ModelMethodProcessor Model 一種類型
ViewMethodReturnValueHandler View 一種類型
ResponseBodyEmitterReturnValueHandler ResponseEntity 一種類型
StreamingResponseBodyReturnValueHandler ResponseEntity 一種類型
HttpHeadersReturnValueHandler HttpHeaders 一種類型
CallableMethodReturnValueHandler Callable 一種類型
DeferredResultMethodReturnValueHandler DeferredResult、ListenableFuture、CompletionStage 一種類型
AsyncTaskMethodReturnValueHandler WebAsyncTask 一種類型
ModelAttributeMethodProcessor @ModelAttribute(require=false) 針對注解
RequestResponseBodyMethodProcessor @ResponseBody 針對注解
ViewNameMethodReturnValueHandler void、CharSequence(V4.2) 多種類型
MapMethodProcessor Map 多種類型
自定義返回值處理器 自定義
ServletModelAttributeMethodProcessor 兜底方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM