其他分享
首页 > 其他分享> > 22.Model、Map原理

22.Model、Map原理

作者:互联网

Model 和 Map

为什么在Model和Map中放值传入后会出现在request的上面。

9.1、源码解析

  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;
      }
  2. 第一步进入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());
  3. 在获取参数阶段,解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对象返回

  4. 反射调用方法

    由于是同一个对象所有 map 和 model中的值都样,所以往map和Model放值都一样

  5. 把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);
        }
        });
        }

标签:Map,22,map,request,Model,model,类中
来源: https://www.cnblogs.com/55zjc/p/16561043.html