我们来了解下ModelAndViewContainer组件---------------【springmvc源码】
接着上一篇的springmvc最简单配置的解析(4)-----------【springmvc源码】,我们继续分析。
在上一篇中的render方法,其实它是最后处理请求的阶段,也就是把请求转换为视图的阶段。它主要应用到ModelAndViewContainer这个类。
ModelAndViewContainer,你可以认为是上下文容器,它主要是承担着整个请求过程中数据的传递工作,但是它在处理保存Model和View之外,还有一些其他功能。请看下面代码:
package org.springframework.web.method.support;
public class ModelAndViewContainer {// 视图,实际使用时可能是String类型的逻辑视图private Object view;// 标记handler是否已经完成请求处理private boolean requestHandled = false;// 默认模型,下文我们可以简单科普下ModelMap继承体系private final ModelMap defaultModel = new BindingAwareModelMap();// redirect时使用的模型,实际使用的是RedirectAttributesModelMapprivate ModelMap redirectModel;// 标记处理器返回redirect视图private boolean redirectModelScenario = false;// redirect时,是否忽略defaultModelprivate boolean ignoreDefaultModelOnRedirect = false;// @SessionAttributes注解使用状态标记,就是是否处理完毕private final SessionStatus sessionStatus = new SimpleSessionStatus();...
}
通过上面,我们可以知道ModelAndViewContain有两个Model,分别为defaultModel和redirectModel;
至于在什么情况下使用哪个,
- defaultModel是默认使用的Model
- redirectModel是用于传递redirect时的Model
- 处理器中使用了Model或ModelMap时,ArgumentResolve会传入defaultModel。defaultModel的话,因为它是BindingAwareModel Map类型,而且继承了ModelMap又实现了Model接口,所以在处理器中使用Model或ModelMap时,其实都是使用同一个对象。-----------Map参数传入的也是这个对象。
- 处理器中RedirectAttributes类型的参数ArgumentResolve会传入redirectModel。redirectModel实际是RedirectAttributesModel Map类型。
下面是ModelAndView的大概属性和方法,
从几张图中,我们能了解到ModleMap这个类,去看看呗,
我们在看下它的内部,
/*** 可以看出ModelMap实际上就是一个LinkedHashMap,且“值”为超类Object类型* 能够放置所有的Java对象*/
public class ModelMap extends LinkedHashMap<String, Object> {public ModelMap() {}// 调用这个构造函数之前会先调用其父类构造函数,得到一个Map对象public ModelMap(String attributeName, Object attributeValue) {addAttribute(attributeName, attributeValue);}// 就是将attributeValue对象放置到Map末尾,同时指定键值为attributeNamepublic ModelMap addAttribute(String attributeName, Object attributeValue) {put(attributeName, attributeValue);return this;}// attributes是一个Map集合;所谓merge无非是将attributes这个集合放置到现有集合的末尾public ModelMap mergeAttributes(Map<String, ?> attributes) {if (attributes != null) {for (Map.Entry<String, ?> entry : attributes.entrySet()) {String key = entry.getKey();if (!containsKey(key)) {put(key, entry.getValue());}}}return this;}//省略一些方法的定义...
}
通过这样,我们可以了解到
ModelAndViewContainer定义了两个ModelMap对象:defaultModel和redirectModel,实际上也就是两个Map<String, Object>1 * 其中defaultModel已经完成了初始化。默认使用defaultModel。2 * 也可以通过其中的方法来设置使用redirectModel,这个是方便移植和使用其它框架而设定的。
虽然上面已经写到了,但是这里重新写一遍,是不是理解更深了点。
但是大家有注意到吗,其实在springmvc最简单配置的解析(3)-------------【springmvc源码】中的invokeHandlerMethod方法是有使用到ModelAndViewContain,因为该方法使用了类似责任链模式,所以就跳过了。那么ModelAndViewContain,它在那里是起到什么作用呢。。。
到这里,我们来了解invokeHandlerMethod这个比较重要的方法。。。
首先我们得知道invokeHandlerMethod方法,它的主要作用是具体执行请求处理。
/*** Invoke the RequestMapping handler method preparing a ModelAndView if view resolution is required.*/
private ModelAndView invokeHandleMethod(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {//step 1、ModelAndView的前世:是一个ModelAndViewContainer实例ModelAndViewContainer mavContainer = new ModelAndViewContainer();/** RequestContextUtils.getInputFlashMap(request)可以获取到request中的attribute,* 并且将所有的request中的attribute放置在mavContainer中,此时使用的是defaultModel*/mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));modelFactory.initModel(webRequest, mavContainer, requestMappingMethod);/* * 在RequestMappingHandlerAdapter中ignoreDefaultModelOnRedirect默认为false*/mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);//省略许多代码...if (asyncManager.hasConcurrentResult()) {//...mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];//...}//step 2、调用handler方法,requestMappingMethod.invokeAndHandle(webRequest, mavContainer);//省略许多代码...//step 3、从mavContainer中获取到ModelAndView实例,返回return getModelAndView(mavContainer, modelFactory, webRequest);
}
或许和之前的有些不一样,但是流程类似。
但是,到了这里大家就明白了吗?MainAndViewResolve。。。
参考资料:
7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解
SpringMVC源码分析(3):分析ModelAndView的形成过程
看透springmvc源码分析与实践 第13章 HandlerAdapter
我们来了解下ModelAndViewContainer组件---------------【springmvc源码】相关推荐
- SpringMVC源码分析(4)剖析DispatcherServlet重要组件
简单介绍了一个请求的处理过程, 简略描述了调用过程,并没有涉及过多细节,如url匹配,报文解析转换等. <SpringMVC源码分析(2)DispatcherServlet的初始化>:介绍 ...
- springMvc源码刨析笔记
springMvc源码刨析笔记 MVC 全名是 Model View Controller,是 模型(model)-视图(view)-控制器(controller) 的缩写, 是⼀种⽤于设计创建 We ...
- 筑基期第一式:SpringMVC源码解析
文章目录 SpringMVC源码解析 SPI机制 案例 SpringMVC中SPI的使用 初始化IOC容器与九大组件 初始化容器 初始化九大组件 小结 SpringMVC如何处理一个请求 doDisp ...
- java注解返回不同消息,SpringMVC源码剖析5:消息转换器HttpMessageConverter与@ResponseBody注解...
转自 [SpringMVC关于json.xml自动转换的原理研究[附带源码分析]](https://www.cnblogs.com/fangj... 部分代码会放在我的的Github:https:// ...
- 简单直接让你也读懂springmvc源码分析(3.1)-- HandlerMethodReturnValueHandler
该源码分析系列文章分如下章节: springmvc源码分析(1)-- DispatcherServlet springmvc源码分析(2)-- HandlerMapping springmvc源码分析 ...
- SpringMVC源码剖析(五)-消息转换器HttpMessageConverter
概述 在SpringMVC中,可以使用@RequestBody和@ResponseBody两个注解,分别完成请求报文到对象和对象到响应报文的转换,底层这种灵活的消息转换机制,就是Spring3.x中新 ...
- SpringMVC源码分析_1 SpringMVC容器启动和加载原理
SpringMVC源码分析_1 SpringMVC启动和加载原理 ...
- 如何在Eclipse中查看Android源码或者第三方组件包源码
文章出处:http://blog.csdn.net/cjjky/article/details/6535426 在学习过程中如果经常阅读源码,理解程度会比较深,学习效率也会比较高,那么如何方便快捷的阅 ...
- SpringMVC源码阅读系列汇总
1.前言 1.1 导入 SpringMVC是基于Servlet和Spring框架设计的Web框架,做JavaWeb的同学应该都知道 本文基于Spring4.3.7源码分析,(不要被图片欺骗了,手动滑稽 ...
最新文章
- 技术人员如何转型为产品经理
- 不要老去打断程序员的工作
- 2728:摘花生(数字金子塔变形)
- 蓝桥杯 ADV-212 算法提高 3-1课后习题2
- linux系统怎么ping命令,Linux系统下的ping命令的使用
- 朗逸发动机型号css和ea211的区别,css发动机是ea211吗
- 无线通信课程实验报告
- 全能地图下载器最终破解版及安装教程【最终破解版、完美注册、最全教程、支持win10】
- 全球及中国钢铁行业供需格局与未来前景分析报告2022版
- java微博模拟登陆_java+selenium模拟登陆新浪微博demo
- python 双冒号_python双冒号
- 50以内的勾股数c语言,50以内勾股数有哪些
- flip game java_LeetCode 293. Flip Game
- word2013 无法撤销解决方法-有效
- 用Python爬取手机APP
- 《创业时代》这部剧或许大家都有看过,里面的郭鑫年(黄轩饰),最终创业成功了吗?
- KMP-Simpsons’ Hidden Talents
- [PC] 2004 忍者神龟2:并肩作战 Teenage Mutant Ninja Turtles2:Battle Nexus
- 利用MDK软件生成bin文件的简单方法
- 乌合之众——群体心理学