- 使用场景
- MapMethodProcessor:类
- ModelMethodProcessor:类
- Model类
- 2.ModelAndViewContainer:类
- 一个小知识点
- 完整的调用逻辑
使用场景
MapMethodProcessor:类
属性:无
行为:下面四个
supportsParameter()、**resolveArgument()是 处理方法参数解析器接口HandlerMethodArgumentResolver接口里的两个方法。 supportsReturnType()、handleReturnValue()是 处理返回值接口**HandlerMethodReturnValueHandler接口里的两个方法。
解析方式:
从mavContainer里拿ModelMap初始化Map和Model
为什么model会和map一样?因为model在解析的时候会被实例化成
ModelMethodProcessor:类
他的解析方法和上面的 MapMethodProcessor差不多。(其实一模一样)
Model类
0)继承关系
1)Model:接口
属性:无
行为:添加属性(object性;k,v型,k必须是String;是否包含某个属性;合并属性;):注意看下面的参数类型
2)RedirectAttributes:接口
属性:无
行为:在前面的基础上多加了addFlashAttribute(),和getFlashAttribute():注意参数类型
3)ModelMap:类
LinkedHashMap
的子类。相当于是一个LinkedHashMap的一个特殊情况
属性:无
行为:添加、取出、合并、判断是否包含某个属性
4)ExtendedModelMap:类
这个类实现了Model,继承了ModelMap。
属性:无
行为:如下,因为实现了Model类,所以必须实现Model里所有的抽象方法,而且把返回类型改成了自身。值得注意的是containsAttribute,因为父类有了,所以就不用实现了。
这些行为的作用:调用ModelMap里和Model里相同的方法去实现Model里的方法。
5)BindingAwareModelMap
属性:无
行为:put、putAll。 他们都调用了自身的removeBindingResultIfNecessary()
2.ModelAndViewContainer:类
属性:view、redirectModel、defaultModel
注意属性的数据类型:Object view、 ModelMap redirectModel、BindingAwareModelMap defaultModel 重定向model是modelMap类型的,也即Map类型。
defaultModel是BindingAwareModelMap类型的,也即是继承ModelMap,实现Model,并且用ModelMap里的方法实现Model里方法的类型
defaultModel是BindingAwareModelMap类型
行为:getView()、setView()、setRedirectModel()、getDefaultModel()、getModel()、添加、添加所有、包含、合并、删除属性。 还有个setViewName()、getViewName()和getView()、setView()作用一模一样
为什么没有getRedirectModel(),getModel()里面会返回,不过会先做判断
一个小知识点
怎么根据forward,redirect就知道转发和重定向?答案如下
完整的调用逻辑
请求处理完成后,所有的数据(视图,model)都被封装到 ModelAndViewContainer mavContainer里,然后接下来就对mavContainer进行处理。
1.DispatcherServlet#doDispatch()
根据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()
创建一个ServletInvocableHandlerMethod,并调用他的invokeAndHandle(),目的是:为了完成请求处理,并且把所有的结果(model,view等)都封装到mavContainer里。
最后调用自身的getModelAndView(),目的是:为了完成把mavContainer里的数据包装到ModelAndView里。
最后把**ModelAndView返回。
把ModelAndView返回给doDispatch()**
3.ServletInvocableHandlerMethod#invokeAndHandle()
调用父类InvocableHandlerMethod的invokeForRequest(),目的是:为了完成请求处理,并得到返回值(就是目标方法的return。),
创建HandlerMethodReturnValueHandlerComposite 类属性,并调用其handleReturnValue(),目的是:为了处理返回值,把处理后的结果放到mavContainer的(view)里。
比如,上面的返回值 forward:/success 这里就是处理forward判断为转发,处理success找到转发路径,把这些东西解析好之后封装到mavContainer里
InvocableHandlerMethod#invokeForRequest()
调用自身getMethodArgumentValues(),目的是:为了拿到所有解析后的args,解析的意思就是实例化参数的。
然后调用自身doInvoke(),目的是,传入args以invoke目标方法,并拿到返回值(目标方法return 值)
getMethodArgumentValues()
调用了父类HandlerMethod里的getMethodParamters(),目的是,为了拿到所有目标方法(即HanlderMethod)里的形参。
有必要说明一下 handler=controller=handlerMethod=Controller类里的一个方法(这个方法就是目标方法)
然后调用了HandlerMethodArgumentResolverComposite#resolveArgument(),目的是,为了解析所有的目标方法里的参数。**这个解析的过程,就是给所有的参数实例化的过程**。
比如,如果参数里有Model、Map类型的参数。解析就是调用专门的解析器(ModelMethodProcessor、MapMethodProcessor)里的resolveArgument()给map赋值。 这个例子中resolveArgument()作用是调用 mavContainer里的getModel()得到mavContainer的ModelMap defaultModel想·想·
doInvoke():举个例子说明一下