使用场景

image.pngimage.png

MapMethodProcessor:类

属性:无

行为:下面四个

image.png

image.png

supportsParameter()、**resolveArgument()是 处理方法参数解析器接口HandlerMethodArgumentResolver接口里的两个方法 supportsReturnType()、handleReturnValue()是 处理返回值接口**HandlerMethodReturnValueHandler接口里的两个方法。

image.pngimage.png

解析方式:

从mavContainer里拿ModelMap初始化Map和Model

为什么model会和map一样?因为model在解析的时候会被实例化成

ModelMethodProcessor:类

他的解析方法和上面的 MapMethodProcessor差不多。(其实一模一样)
image.png image.png

Model类

0)继承关系

image.png

1)Model:接口

属性:无

行为:添加属性(object性;k,v型,k必须是String;是否包含某个属性;合并属性;):注意看下面的参数类型

image.png

2)RedirectAttributes:接口

属性:无

行为:在前面的基础上多加了addFlashAttribute(),和getFlashAttribute():注意参数类型

image.png

3)ModelMap:类

LinkedHashMap的子类。相当于是一个LinkedHashMap的一个特殊情况

感觉她和Model没啥区别不过一个是接口一个是类而已。

属性:无

行为:添加、取出、合并、判断是否包含某个属性

image.pngimage.pngimage.pngimage.png
**

4)ExtendedModelMap:类

image.png

这个类实现了Model,继承了ModelMap。

image.png

属性:无

行为:如下,因为实现了Model类,所以必须实现Model里所有的抽象方法,而且把返回类型改成了自身。值得注意的是containsAttribute,因为父类有了,所以就不用实现了。

这些行为的作用:调用ModelMap里和Model里相同的方法去实现Model里的方法。

image.pngimage.png

5)BindingAwareModelMap

属性:无

行为:put、putAll。 他们都调用了自身的removeBindingResultIfNecessary()

image.png

2.ModelAndViewContainer:类

属性:view、redirectModel、defaultModel

注意属性的数据类型:Object view、 ModelMap redirectModel、BindingAwareModelMap defaultModel 重定向model是modelMap类型的,也即Map类型。
defaultModel是BindingAwareModelMap类型的,也即是继承ModelMap,实现Model,并且用ModelMap里的方法实现Model里方法的类型

image.png

defaultModel是BindingAwareModelMap类型
image.png

行为:getView()、setView()、setRedirectModel()、getDefaultModel()、getModel()、添加、添加所有、包含、合并、删除属性。 还有个setViewName()、getViewName()和getView()、setView()作用一模一样

为什么没有getRedirectModel(),getModel()里面会返回,不过会先做判断

image.pngimage.pngimage.pngimage.png

一个小知识点

怎么根据forward,redirect就知道转发和重定向?答案如下
image.pngimage.png

完整的调用逻辑

请求处理完成后,所有的数据(视图,model)都被封装到 ModelAndViewContainer mavContainer里,然后接下来就对mavContainer进行处理。

1.DispatcherServlet#doDispatch()

image.png

根据request,找到相应的requestMapping,然后用他的getHandler返回请求执行链
(注意!这是会根据request封封装一个handler,然后再用这个handler封装成一个HandlerExecutionChain。所以5个HandlerMapping的作用仅仅是把request同java的handler(也可以看成controller,即java的类和方法)建立映射。)
,用请求执行链里的handler再找到对应HanlderAdapter,然后让adapter去handle(handler)
总结:一系列操作就是为了根据request,创建相应的handler,然后用handler找到相应的handlerAdapter去handle(handler),目的是为了得到处理后的ModelAndView(这里面存放了ModelMap model、String view)
然后调用自身的processDispatchResult()去处理这个mv。
processDispatchResult()拿到mv之后调用本类的render()去处理mv,目的是调用view自己的render去渲染自己。

2.RequestMappingHandlerAdapter#invokeHandlerMethod()

image.pngimage.png
创建一个ServletInvocableHandlerMethod,并调用他的invokeAndHandle(),目的是:为了完成请求处理,并且把所有的结果(model,view等)都封装到mavContainer里。
最后调用自身的getModelAndView(),目的是:为了完成把mavContainer里的数据包装到ModelAndView里。
最后把**ModelAndView返回。
把ModelAndView返回给doDispatch()**

3.ServletInvocableHandlerMethod#invokeAndHandle()

image.pngimage.pngimage.pngimage.png
调用父类InvocableHandlerMethod的invokeForRequest(),目的是:为了完成请求处理,并得到返回值(就是目标方法的return。image.png),
创建HandlerMethodReturnValueHandlerComposite 类属性,并调用其handleReturnValue(),目的是:为了处理返回值,把处理后的结果放到mavContainer的(view)里。

比如,上面的返回值 forward:/success 这里就是处理forward判断为转发,处理success找到转发路径,把这些东西解析好之后封装到mavContainer里

InvocableHandlerMethod#invokeForRequest()

image.pngimage.pngimage.png

调用自身getMethodArgumentValues(),目的是:为了拿到所有解析后的args,解析的意思就是实例化参数的。
然后调用自身doInvoke(),目的是,传入args以invoke目标方法,并拿到返回值(目标方法return 值)

getMethodArgumentValues()

image.pngimage.pngimage.pngimage.png
调用了父类HandlerMethod里的getMethodParamters(),目的是,为了拿到所有目标方法(即HanlderMethod)里的形参。

有必要说明一下 handler=controller=handlerMethod=Controller类里的一个方法(这个方法就是目标方法)

然后调用了HandlerMethodArgumentResolverComposite#resolveArgument(),目的是,为了解析所有的目标方法里的参数。**这个解析的过程,就是给所有的参数实例化的过程**。

比如,如果参数里有Model、Map类型的参数。解析就是调用专门的解析器(ModelMethodProcessor、MapMethodProcessor)里的resolveArgument()给map赋值。 这个例子中resolveArgument()作用是调用 mavContainer里的getModel()得到mavContainer的ModelMap defaultModel想·想·

doInvoke():举个例子说明一下

image.png

4.AbstractView的render(),他调用自身的renderMergedOutputModel(),他又调用本类的exposeModelAsRequestAttributes(),里面就把model里 的值转成了request里。

image.png