调戏源码之Spring MVC(二)
上篇对SpringMVC的基本流程做了介绍,重点讲了HandlerExecutionChain对象的获取以及通过处理器适配器执行真正的处理器方法得到ModelAndView对象.后面视图解析及渲染都是一笔带过.本文将具体介绍他们以及自己在写上篇博客是的疑问:
1. 为什么是service方法?
2. 到底怎么找到Handler的?
3. 视图解析和渲染做了什么?
为什么是service方法?
简单搜了一些资料,大多讲的是容器启动时执行init()方法,发送http请求执行service方法.但我关心的是:谁指定了要执行service方法,在哪里,怎么做的?
这个是后重点已经不是service方法了,包括init,destory在内.它们的执行好像收到了某个东西的控制.没错Servlet容器的嫌疑最大.
这已经不属于SpringMVC的范畴了,放着以后再研究.
到底怎么找到Handler的?
第一行代码得到一个名为methodResolver的方法解析器.
可以看到解析器中有一个名为mapping的HashMap,HashMap中又有table,而table中有一个元素的key和value分别对应Url请求的方法和@RequestMapping的value属性值.
methodResolver内部结构我没有完全搞明白,但至少知道它包含了要执行的方法和对应的@RequestMapping注解value属性值.这就够了.接下来肯定是截取Url末尾来与注解value值做匹配以执行相应的方法.
看到没?通过调用methodResolver的resolveHandlerMethod方法,将request作为参数传进去,得到了一个名为”itemList”的Method方法对象.
F5跟踪resolveHandlerMethod方法,该方法主要做了一下事情:
- 截取Url得到lookupPath
- 匹配到正确的方法后放入Map对象targetHandlerMethods.
- 返回targetHandlerMethods对象中的Method对象.
视图解析
让我们从processDispatchResult方法开始:
render是递交,返回的意思,再看参数就知道.程序准备将模型填进视图返回给用户了.
render内部有做了什么呢?
首先把视图名解析成View对象,可以看到参数里表中有mv.getModelInternal()就是模型,可是进到方法内部却看到模型并没有被使用:
看!除了参数列表,方法体重你并没有看到model.不知道为什么.
所以视图解析就是把一个逻辑视图名称通过VIewResolver解析成View对象.
视图渲染
这里就是视图渲染了,他做了些什么呢?
要点儿紧的是这行代码,内部是这样的下:
1. 将model设置成request的Attribute
2. 获取RequestDisPatcher对象
exposeModelAsRequestAttributes方法是这样的:
最后,调用RequestDisPatcher对象的forword方法.
forword方法大家在熟悉不过了.到儿,整个SpringMVC流程就基本走完了!