通过前面对 Controller method 参数绑定的分析,我们知道, 被 @RequestMapping 标记 handler method 的执行是通过调用 RequestMappingHandlerAdapter#handle()

RequestMappingHandlerAdapter#handle() 具体的调用过程如下:
RequestMappingHandlerAdapter2.png

参数解析、handler method 的执行 和 对返回值的处理,最终是通过 ServletInvocableHandlerMethod#invokeAndHandle() 来处理的。

ServletInvocableHandlerMethod#invokeAndHandle() 的处理过程如下: ServletInvocableHandlerMethod2.png

// org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest
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);
}

1、首先,通过 HandlerMethodArgumentResolver 解析出方法执行所需要的参数,然后通过反射调用 handler method 来执行。
2、如果 handler method 的返回值为空,则看是否跳过返回值处理和视图解析,直接返回
3、通过 HandlerMethodReturnValueHandler 来处理 handler method 的返回值
4、通过 ModelAndViewContainer 对象组装出 ModelAndView 对象进行返回。
(如果 requestHandled=true,则直接返回 null,不经过视图解析)

补充:SpringMVC 相关的对象、实体

ModelAndViewContainer

ModelAndViewContainer 用于记录 HandlerMethodArgumentResolverHandlerMethodReturnValueHandler 在调用 handler method 过程中做出的与模型和视图相关的决策。

public class ModelAndViewContainer {

    // 在重定向的时候是否使用默认 Model 的内容
    private boolean ignoreDefaultModelOnRedirect = false;

    @Nullable
    private Object view;

    // 默认模型在实例化时自动创建
    private final ModelMap defaultModel = new BindingAwareModelMap();

    // 重定向的 Model 
    @Nullable
    private ModelMap redirectModel;

    // 标记是否是重定向的场景
    // 如果是重定向场景,getModel()返回重定向模型而不是默认模型
    private boolean redirectModelScenario = false;

    @Nullable
    private HttpStatus status;

    private final SessionStatus sessionStatus = new SimpleSessionStatus();

    // 用于标记请求已被直接处理,不需要视图解析
    private boolean requestHandled = false;
}

ModelAndView

ModelAndView 是 Spring MVC 框架中模型和视图的持有者,用于表示 handler method 返回的模型和视图,最终会由 DispatcherServlet 解析。

public class ModelAndView {

    /** View instance or view name String. 
     * View 对象 或者 String 类型的 view name。
     * */
    @Nullable
    private Object view;

    /** Model Map. */
    @Nullable
    private ModelMap model;

    /** Optional HTTP status for the response. */
    @Nullable
    private HttpStatus status;
}

View:

视图可以采用 String 类型的视图名称 或者直接指定 View 对象,需要由 ViewResolver 解析。

Model:

模型采用的是 Map 类型,允许使用名称来访问值对象,也就是使用 Map 的形式访问整个模型对象。

Model.png

BindingAwareModelMap 是 SpringMVC 向 handler method 暴露的类。
通常是通过 Model 接口来声明使用的,不需要在用户代码中构建它。

RedirectAttributesModelMap 是重定向属性的 ModelMap 实现。
提供了一个它提供了闪存 mode 属性的地方,这样重定向的model 属性就可以在重定向中生存,而无需嵌入重定向URL中。