一、概述
前面我们分析了Spring MVC执行的核心思想,其核心在DispatcherServlet这个类的doDispatch方法中,上一篇我们解析了doDispatch方法的功能和作用,这一篇我们来解析一下doDispatch方法里面的几个核心方法。
二、方法详解
首先我们分析下Handler和HandlerAdapter是如何获取的
我们debug模式进入getHandler方法里面,如下图,我们可以观察到有三个Handler备选,程序会遍历三个Handler找出合适的Handler,最后我们获得的HandlerMapping是第二个RequestMappingHandlerMapping
程序继续走,走到getHandlerAdapter方法这一行,我们依然断点进入,如下图,其逻辑和上面getHandler基本类似,遍历出合适的Adapter,最后第三个RequestMappingHandlerAdapter符合要求。
继续往下分析,我们主要关注的方法ha.handle()方法,如下图
该方法的第三个参数我们看下具体的值
我们可以看到该方法的handler已经指定到我们DemoController类中的goTestPage()方法了,然后我们进入该方法内部分析一下
如上图,代码进入invokeHandlerMethod()方法,我们分析其内部实现,如下图
图中这些方法都是在为后面的invokeAndHandle()方法设置一些属性和值,我们接下来直接关注invokeAndHandle()方法
进入invokeAndHandle()方法,我们关注invokeForRequest()方法
该方法的返回值是doInvoke()方法,doInvoke的底层是用反射实现对目标方法的调用,最后获取返回值“success”,如下图
再获取到方法的返回值之后,我们可以看到invokeHandlerMethod()方法最终返回的是getModelAndView()方法,我们再看看该方法
如上图,我们可以看到mavContainer已经存在view="success",最终我们返回的ModelAndView对象中包含有view:"success",model:{date:Date}
最后我们再观察上图中方法,看它是如何渲染页面的
如上图我们关注resolveViewName()方法
如上图,我们可以看到this.viewResolvers的prefix和suffix属性,就是我们springmvc.xml配置文件中配置的视图解析器属性,接下来我们再看看viewResolver.resolveViewName方法,如下图
该方法的第一个判断isCache用来判断该视图是否已经解析过,用来做重定向的跳转,我们关注createView方法,如下图
上图方法的作用就是拼接好视图所对应的路径,交于父类方法解析,父类的方法最终会调用如下图方法
红框框柱的部分就是视图的路径,最后tomcat处理好jsp的解析,并将其渲染到页面上。
三、小结
本章我们详细的剖析了Spring MVC是如何处理请求以及响应视图的,其中HandlerAdapter的设计是一种适配器模式,在我们解析框架的时候也可以处处留意下Spring框架在设计的时候用到了哪些设计模式,看看大师级别的他们是如何灵活运用设计模式的,从中学习精髓以此来提高我们的架构设计思想。
感兴趣的读者朋友可以 关注本公众号,和我们一起学习探究。
本人因所学有限,如有错误之处,望请各位指正!