Spring的Model 和 Map的原理
Model 和 Map
为什么在Model和Map中放值传入后会出现在request的上面。
9.1、源码解析
准备测试代码
@GetMapping("/goto")
public String go(HttpServletRequest request,
Map<String,Object> map,
Model model){ request.setAttribute("msg","传过来....");
map.put("map","map hello word!!");
model.addAttribute("model","model hello word!!"); return "forward:success";
} @ResponseBody
@GetMapping("/success")
public Map success(@RequestAttribute(value = "msg",required = false) String msg,
HttpServletRequest request){
Map<String,Object> hashMap = new HashMap<>(); Object msg1 = request.getAttribute("msg");
Object map = request.getAttribute("map");
Object model = request.getAttribute("model"); hashMap.put("map1",map);
hashMap.put("model",model);
hashMap.put("msg1",msg1); return hashMap;
}
第一步进入DispatchServlet 的 doDispatch中
主要的三步
DispatchServlet类中的
doDispatch方法
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);//获取反射的方法处理器
// Determine handler adapter for the current request.
//获取参数处理器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Actually invoke the handler.
//反射执行方法和解析Model和Map
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
在获取参数阶段,解Model和Map
获取Map 的 处理器器 MapMethodProcessor
处理Map这个参数
MapMethodProcessor类中的
@Override
@Nullable
public Object resolveArgument(MethodParameter parameter,
@Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
@Nullable WebDataBinderFactory binderFactory) throws Exception {
Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure"); return mavContainer.getModel();
} 然后进入ModelAndViewContainer类中的
private final ModelMap defaultModel = new BindingAwareModelMap();
public ModelMap getModel() {
if (useDefaultModel()) {
return this.defaultModel;//获取ModelMap
}
......
把这个ModelMap对象返回
获取Model的 处理器器 ModelMethodProcessor
处理Model这个参数
ModelMethodProcessor类中的
@Override
@Nullable
public Object resolveArgument(MethodParameter parameter,
@Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
@Nullable WebDataBinderFactory binderFactory) throws Exception { Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure");
return mavContainer.getModel();
} 然后进入ModelAndViewContainer类中的
private final ModelMap defaultModel = new BindingAwareModelMap();
public ModelMap getModel() {
if (useDefaultModel()) {
return this.defaultModel;//获取ModelMap 这个和那个Map获取的是同一个
}
......
把同一个ModelMap对象返回

反射调用方法
由于是同一个对象所有 map 和 model中的值都样,所以往map和Model放值都一样



把model和map的数据放入request
- 第一步
ServletInvocableHandlerMethod类中
invokeAndHandle方法
//获取返回值的一个处理器
try {
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue),
mavContainer, webRequest);
}
HandlerMethodReturnValueHandlerComposite类中的
HandlerMethodReturnValueHandler方法 进行获取
这里获取的
ViewNameMethodReturnValueHandler这个处理器
第二步
把Map和 Model携带的参数和返回值(路径)进行整合为ModelAndView
RequestMappingHandlerAdapter类中
handleInternal方法
...
ModelAndView mav;
...
mav = invokeHandlerMethod(request, response, handlerMethod);
...
第三步
准备派发和放入参数
DispatchServlet类中的
doDispatch方法
render(mv, request, response);
view.render(mv.getModelInternal(), request, response); AbstractView类中的
render方法
//把BindingAwareModelMap的参数封装为Map
Map<String, Object> mergedModel = createMergedOutputModel(model,
request, response);
prepareResponse(request, response);
//准备方法和放入参数到reques中
renderMergedOutputModel(mergedModel, getRequestToExpose(request),
response);
InternalResourceView类中的
renderMergedOutputModel
// Expose the model object as request attributes.
exposeModelAsRequestAttributes(model, request);//把参数放入到request中
AbstractView类中的
//把参数放入到原生的request域中
protected void exposeModelAsRequestAttributes(Map<String, Object> model,
HttpServletRequest request) throws Exception {
model.forEach((name, value) -> {
if (value != null) {
request.setAttribute(name, value);
}
else {
request.removeAttribute(name);
}
});
}

Spring的Model 和 Map的原理的更多相关文章
- Spring框架系列(14) - SpringMVC实现原理之DispatcherServlet处理请求的过程
前文我们有了IOC的源码基础以及SpringMVC的基础,我们便可以进一步深入理解SpringMVC主要实现原理,包含DispatcherServlet的初始化过程和DispatcherServlet ...
- 理解Spring MVC Model Attribute和Session Attribute
作为一名 Java Web 应用开发者,你已经快速学习了 request(HttpServletRequest)和 session(HttpSession)作用域.在设计和构建 Java Web 应用 ...
- SpringMVC(二)--处理数据模型、ModelAndView、Model、Map、重定向、@ModelAttribute、
1.处理模型数据 Spring MVC 提供了以下几种途径输出模型数据: – ModelAndView:处理方法返回值类型为 ModelAndView 时, 方法体即可通过该对象添加模型数据 ...
- Spring中Model、ModelMap及ModelAndView之间的区别
Spring中Model.ModelMap及ModelAndView之间的区别 1. Model(org.springframework.ui.Model)Model是一个接口,包含addAttr ...
- HashMap,Hashtable,ConcurrentHashMap 和 synchronized Map 的原理和区别
HashMap 是否是线程安全的,如何在线程安全的前提下使用 HashMap,其实也就是HashMap,Hashtable,ConcurrentHashMap 和 synchronized Map 的 ...
- 【译】理解Spring MVC Model Attribute 和 Session Attribute
作为一名 Java Web 应用开发者,你已经快速学习了 request(HttpServletRequest)和 session(HttpSession)作用域.在设计和构建 Java Web 应用 ...
- ModelAndView存取数Model、Map、ModelMap
1.从名字上看ModelAndView中的Model代表模型,View代表视图,这个名字就很好地解释了该类的作用.(对应mvc配置,寻找模型,返回视图.) 2.业务处理器调用模型层处理完用户请求后,把 ...
- Spring Boot 实现配置文件加解密原理
Spring Boot 配置文件加解密原理就这么简单 背景 接上文<失踪人口回归,mybatis-plus 3.3.2 发布>[1] ,提供了一个非常实用的功能 「数据安全保护」 功能,不 ...
- Spring框架系列(13) - SpringMVC实现原理之DispatcherServlet的初始化过程
前文我们有了IOC的源码基础以及SpringMVC的基础,我们便可以进一步深入理解SpringMVC主要实现原理,包含DispatcherServlet的初始化过程和DispatcherServlet ...
随机推荐
- 169. Majority Element - LeetCode
Question 169. Majority Element Solution 思路:构造一个map存储每个数字出现的次数,然后遍历map返回出现次数大于数组一半的数字. 还有一种思路是:对这个数组排 ...
- Python模块Ⅰ
Python模块Ⅰ part1 模块的定义/取别名 自定义模块 什么是模块:模块的本质就是.py文件,封装语句的最小单位 模块中出现的变量,for循环,if结构,函数定义...称为模块成员 模块的运行 ...
- 2021年第十二届蓝桥杯javaA组省赛部分题目
试题 D: 路径 本题总分:10 分 [问题描述] 小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图 中的最短路径. 小蓝的图由 2021 个结点组成,依次编号 1 至 2021. 对 ...
- 《HALCON数字图像处理》第六章笔记
目录 第六章 图像增强 图像增强的概念和分类 灰度变换 直方图处理 图像的平滑 图像的锐化 图像的彩色增强 我在Gitee上建了个仓库,会将学习书本的时候打的一些代码上传上去,笔记中所有代码都在仓库里 ...
- DYOJ 【20220317模拟赛】瞬间移动 题解
瞬间移动 题意 三维空间中从 \((0,0,0)\) 开始,每次移动 1,问刚好走 \(N\) 次能到 \((X,Y,Z)\) 的方案数 \(N\le10^7\),答案模 \(998244353\) ...
- Java 多线程共享模型之管程(下)
共享模型之管程 wait.notify wait.notify 原理 Owner 线程发现条件不满足,调用 wait 方法,即可进入 WaitSet 变为 WAITING 状态 BLOCKED 和 W ...
- WinForms获得已打开窗体的引用
更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月6日. 对于已经打开的窗口,可以通过Application.OpenForms属性进行获得.该属性是一个FormCollectio ...
- JS:三目运算符
语法:条件表达式?表达式1:表达式0 注:当条件表达式为true则选择表达式1,反之false则选择表达式0 例: var a = 0; var b = 1; re=a>b?a:b consol ...
- cve_2019_0708_bluekeep漏洞
一.环境说明 kali linux windows 7 sp1 二.cve_2019_0708_bluekeep漏洞利用 msf5 auxiliary(dos/windows/rdp/ms12_020 ...
- DNS原理&ssh
作用:实现域名的解析! www.baidu.com => 14.215.177.37 域名: www.baidu.com 实际域名为: www.baidu.com. 域名的解析,是反向的. 最后 ...