springmvc源码笔记-HandlerMethodReturnValueHandler

2022年6月16日 346点热度 0人点赞 0条评论

返回值解析器

用于对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 兜底方法

王谷雨

一个苟且偷生的java程序员

文章评论