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)文章
spring boot使用WebClient調(diào)用HTTP服務(wù)代碼示例
這篇文章主要介紹了spring boot使用WebClient調(diào)用HTTP服務(wù)代碼示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-12-12MyBatis的注解使用、ORM層優(yōu)化方式(懶加載和緩存)
這篇文章主要介紹了MyBatis的注解使用、ORM層優(yōu)化方式(懶加載和緩存),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10