Spring的Model?和?Map的原理源碼解析
Model 和 Map
為什么在Model和Map中放值傳入后會出現(xiàn)在request的上面。
9.1、源碼解析
準(zhǔn)備測試代碼
@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;
}第一步進(jìn)入DispatchServlet 的 doDispatch中
主要的三步
DispatchServlet類中的
doDispatch方法
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);//獲取反射的方法處理器
// Determine handler adapter for the current request.
//獲取參數(shù)處理器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Actually invoke the handler.
//反射執(zhí)行方法和解析Model和Map
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());在獲取參數(shù)階段,解Model和Map
- 獲取Map 的 處理器器 MapMethodProcessor
- 處理Map這個參數(shù)
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();
}
然后進(jìn)入ModelAndViewContainer類中的
private final ModelMap defaultModel = new BindingAwareModelMap();
public ModelMap getModel() {
if (useDefaultModel()) {
return this.defaultModel;//獲取ModelMap
}
......- 把這個ModelMap對象返回
- 獲取Model的 處理器器 ModelMethodProcessor
- 處理Model這個參數(shù)
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();
}
然后進(jìn)入ModelAndViewContainer類中的
private final ModelMap defaultModel = new BindingAwareModelMap();
public ModelMap getModel() {
if (useDefaultModel()) {
return this.defaultModel;//獲取ModelMap 這個和那個Map獲取的是同一個
}
......把同一個ModelMap對象返回

反射調(diào)用方法
由于是同一個對象所有 map 和 model中的值都樣,所以往map和Model放值都一樣



把model和map的數(shù)據(jù)放入request
第一步
ServletInvocableHandlerMethod類中
invokeAndHandle方法
//獲取返回值的一個處理器
try {
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue),
mavContainer, webRequest);
}
HandlerMethodReturnValueHandlerComposite類中的
HandlerMethodReturnValueHandler方法 進(jìn)行獲取這里獲取的ViewNameMethodReturnValueHandler這個處理器

第二步
把Map和 Model攜帶的參數(shù)和返回值(路徑)進(jìn)行整合為ModelAndView
RequestMappingHandlerAdapter類中
handleInternal方法
...
ModelAndView mav;
...
mav = invokeHandlerMethod(request, response, handlerMethod);
...第三步
準(zhǔn)備派發(fā)和放入?yún)?shù)
DispatchServlet類中的
doDispatch方法
render(mv, request, response);
view.render(mv.getModelInternal(), request, response);
AbstractView類中的
render方法
//把BindingAwareModelMap的參數(shù)封裝為Map
Map<String, Object> mergedModel = createMergedOutputModel(model,
request, response);
prepareResponse(request, response);
//準(zhǔn)備方法和放入?yún)?shù)到reques中
renderMergedOutputModel(mergedModel, getRequestToExpose(request),
response);
InternalResourceView類中的
renderMergedOutputModel
// Expose the model object as request attributes.
exposeModelAsRequestAttributes(model, request);//把參數(shù)放入到request中
AbstractView類中的
//把參數(shù)放入到原生的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);
}
});
}
到此這篇關(guān)于Spring的Model 和 Map的原理源碼解析的文章就介紹到這了,更多相關(guān)Spring Model 和 Map內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot整合Dozer實(shí)現(xiàn)深度復(fù)制的方法
Dozer是一種Java?Bean到Java?Bean的映射器,遞歸地將數(shù)據(jù)從一個對象復(fù)制到另一個對象,它是一個強(qiáng)大的,通用的,靈活的,可重用的和可配置的開源映射框架,本文給大家介紹Springboot整合Dozer的相關(guān)知識,感興趣的朋友跟隨小編一起看看吧2022-03-03
Java內(nèi)存模型之重排序的相關(guān)知識總結(jié)
重排序是指編譯器和處理器為了優(yōu)化性能而對指令序列進(jìn)行重新排序的一種手段,文中詳細(xì)介紹了Java重排序的相關(guān)知識,需要的朋友可以參考下2021-06-06
Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type
這篇文章主要介紹了Kotlin基礎(chǔ)教程之Run,標(biāo)簽Label,函數(shù)Function-Type的相關(guān)資料,需要的朋友可以參考下2017-05-05
Java國際化簡介_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家簡單介紹了Java國際化的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
java實(shí)現(xiàn)百度坐標(biāo)的摩卡托坐標(biāo)與火星坐標(biāo)轉(zhuǎn)換的示例
這篇文章主要介紹了java實(shí)現(xiàn)百度坐標(biāo)的摩卡托坐標(biāo)與火星坐標(biāo)轉(zhuǎn)換的示例,需要的朋友可以參考下2014-03-03
Eclipse下基于Java的OpenCV開發(fā)環(huán)境配置教程
這篇文章主要為大家詳細(xì)介紹了Eclipse下基于Java的OpenCV開發(fā)環(huán)境配置教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-07-07
Java并發(fā)編程示例(六):等待線程執(zhí)行終止
這篇文章主要介紹了Java并發(fā)編程示例(六):等待線程執(zhí)行終止,在本節(jié),示例程序演示等待初始化方法完成后,再去執(zhí)行其他任務(wù),需要的朋友可以參考下2014-12-12
在SpringBoot中,如何使用Netty實(shí)現(xiàn)遠(yuǎn)程調(diào)用方法總結(jié)
我們在進(jìn)行網(wǎng)絡(luò)連接的時候,建立套接字連接是一個非常消耗性能的事情,特別是在分布式的情況下,用線程池去保持多個客戶端連接,是一種非常消耗線程的行為.那么我們該通過什么技術(shù)去解決上述的問題呢,那么就不得不提一個網(wǎng)絡(luò)連接的利器——Netty,需要的朋友可以參考下2021-06-06

