通过前面对 Controller method 参数绑定的分析,我们知道, 被 @RequestMapping 标记 handler method 的执行是通过调用 RequestMappingHandlerAdapter#handle()
。
RequestMappingHandlerAdapter#handle()
具体的调用过程如下:
参数解析、handler method 的执行 和 对返回值的处理,最终是通过 ServletInvocableHandlerMethod#invokeAndHandle()
来处理的。
ServletInvocableHandlerMethod#invokeAndHandle()
的处理过程如下:
// 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
用于记录 HandlerMethodArgumentResolver
和 HandlerMethodReturnValueHandler
在调用 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 的形式访问整个模型对象。
BindingAwareModelMap
是 SpringMVC 向 handler method 暴露的类。
通常是通过 Model 接口来声明使用的,不需要在用户代码中构建它。
RedirectAttributesModelMap
是重定向属性的 ModelMap 实现。
提供了一个它提供了闪存 mode 属性的地方,这样重定向的model 属性就可以在重定向中生存,而无需嵌入重定向URL中。