这篇文章主要介绍了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 Model 和 Map内容请搜索编程学习网以前的文章希望大家以后多多支持编程学习网!
沃梦达教程
本文标题为:Spring的Model 和 Map的原理源码解析
基础教程推荐
猜你喜欢
- JDK数组阻塞队列源码深入分析总结 2023-04-18
- java实现多人聊天系统 2023-05-19
- ConditionalOnProperty配置swagger不生效问题及解决 2023-01-02
- java基础知识之FileInputStream流的使用 2023-08-11
- Java实现查找文件和替换文件内容 2023-04-06
- Java文件管理操作的知识点整理 2023-05-19
- springboot自定义starter方法及注解实例 2023-03-31
- Java实现线程插队的示例代码 2022-09-03
- Java数据结构之对象比较详解 2023-03-07
- Java并发编程进阶之线程控制篇 2023-03-07