ModelAndView源码详解以及和Map,Model的区别

我们通过debug方式阅读源码来探究ModelAndView执行流程,在这个过程中我们不需要每行代码都弄懂,从程序开始到结束我们只需关心我们关注的点,ModelAndView的作用以及和Model,Map的区别会在文章末尾揭示

这是ModelAndView类的主要结构:

在这里插入图片描述

其中的ModelMap可以看作是一个Map实现类

在这里插入图片描述

ModelAndView我们用来无非是往作用域传值和跳转页面,我们来看这两个方法:

  • mav.addObject:
    在这里插入图片描述
    我们可以看出其作用就相当于往map中添加键值对

  • mav.setViewName():

public void setViewName(@Nullable String viewName) {
		this.view = viewName;
	}

它是通过字符串的形式往成员变量中赋值

通过debug模式开始测试方法

1.这是我们这个程序的一个controller

在这里插入图片描述

2.

这三个箭头是我们需要关注的地方,现在开始运行,发现有很多我们并不知道的类和方法,但我们知道,我们的请求是通过DispatcherServlet被分发的,所以我们找到对应的类,如下图箭头所示,在相应的行打上断点,我们可以发现mv就是一个ModelAndView对象,此时的mv对象还为null,因为还没运行这个断点
在这里插入图片描述

3.

通过包围断点行的try—catch块我们可以判断出:
在这里插入图片描述下一步要执行的必定是processDispatchResult这个方法,我们可以看一下ha.handle()方法执行后的结果

4.在这里插入图片描述

我们可以发现mv对象已经经过处理,携带了转发的试图名和往作用域添加的对象,具体执行过程在这里不是我们讨论的重点,下一步就是执行processDispatchResult()方法,通过字面意思可以了解到这个方法就是处理分发的结果,processDispatchResult()执行完后DispatcherServlet流程也就结束,因此我们进入这个方法一探究竟

5.

在这里插入图片描述
上面的if (exception != null)表示遇到异常后的处理,我们不需要关注,直接看下面被标记的行,也就是进入processDispatchResult()方法后会执行的代码,它将我们之前的mv对象传进来,我们进入这个方法

6.

在这里插入图片描述

发现resolveViewName,它的作用是解析视图名,返回view对象,它分析出的结果是将我们添加的视图名映射到对应的视图解析器,我们继续往reder方法下面走,我们发现了上一步的view对象已经被解析出来,正是我们自己配置的内容
在这里插入图片描述
但是这个render方法对应的是view接口中的方法,但是实现的却是一个抽象类AbstractView,我们进去看一下

void render(@Nullable Map<String, ?> model,
			HttpServletRequest request, HttpServletResponse response) throws Exception;
7.

在这里插入图片描述
我们看到这个方法中首先创建了Map对象mergedModel,并将之前的mv当作model参数传入,这里我们需要关注renderMergedOutputModel,因为它操作着我们的mv对象,

在这里插入图片描述

8.

首先第一个方法,通过字面意思我们可以看出它的大概意思:将model暴露为一个request,我们进入该方法:
在这里插入图片描述
结果一目了然:
通过循环的方式取出map中的键值对,并通过request.setAttribute()方法往作用域中添加值

9.

接着这个方法往下走:在这里插入图片描述我们可以看到创建了一个dispatcherPath的路径,我们接着往下看:
RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);

在这里插入图片描述

RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);帮我们获得请求转发的一个对象,并在最后实现了转发功能,跳转到我们指定的路径

总结:

通过对ModleAndView的源码分析,我们知道通过ModelAndView放作用域中放值其实是往request域中增加属性,并通过请求转发跳转到我们制定的资源路径

Map和ModelAndView

我们再次通过debug模式来分析:
在这里插入图片描述
我们发现:
通过map的方式和通过ModelAndView的作用是一模一样的,map也是通过ModelAndView来实现的

Model和ModelAndView

不用多说,通过Model的方式和通过ModelAndView的作用是一模一样的,Model也是通过ModelAndView来实现的

发布了37 篇原创文章 · 获赞 11 · 访问量 3893

猜你喜欢

转载自blog.csdn.net/Alphr/article/details/104693727