从名字上看,HandlerAdapter是一个适配器。因为Spring MVC中Handler可以是任意形式的,只要能够处理请求便可。但是把请求交给Servlet的时候,由于Servlet的方法结构都是doService(HttpServletRequest req, HttpServletResponse resp)形式的,要让固定的Servlet处理方法调用Handler来进行处理,这一步工作便是HandlerAdapter要做的事。
2.6 HandlerExceptionResolver
从组件的名字上看,HandlerExceptionResolver是用来处理Handler产生的异常情况的组件。具体来说,此组件的作用是根据异常设置ModelAndView,之后交给渲染方法进行渲染,渲染方法会将ModelAndView渲染成页面。不过要注意,HandlerExceptionResolver只用于解析对请求做处理阶段产生的异常,渲染阶段的异常不归它管,这也是Spring MVC 组件设计的一大原则—分工明确、互不干涉。
2.7 RequestToViewNameTranslator
RequestToViewNameTranslator组件的作用是从请求中获取ViewName。因为ViewResolver根据ViewName查找View,但有的Handler处理完成之后,没有设置View,也没有设置ViewName,便要通过这个组件来从请求中查找ViewName。
2.8 ViewResolver
ViewResolver即视图解析器,相信大家对这个组件应该很熟悉了。通常在Spring MVC的配置文件中,都会配上一个实现类来进行视图解析。这个组件的主要作用是将String类型的视图名和Locale解析为View类型的视图,只有一个resolveViewName()方法。从方法的定义可以看出,Controller层返回的String类型的视图名viewName最终会在这里被解析成为View。View是用来渲染页面的,也就是说,它会将程序返回的参数和数据填入模板中,生成HTML文件。ViewResolver在这个过程中主要做两件大事:ViewResolver会找到渲染所用的模板(第一件大事)和所用的技术(第二件大事,其实也就是找到视图的类型,如JSP)并填入参数。默认情况下,Spring MVC会为我们自动配置一个InternalResourceViewResolver,是针对JSP类型视图的。
2.9 FlashMapManager
说到FlashMapManager组件,得先说一下FlashMap。
FlashMap用于重定向时的参数传递,比如在处理用户订单时,为了避免重复提交,可以处理完post请求后重定向到一个get请求,这个get请求可以用来显示订单详情之类的信息。这样做虽然可以规避用户重新提交订单的问题,但是在这个页面上要显示订单的信息,这些数据从哪里获取呢?因为重定向是没有传递参数这一功能的,如果不想把参数写进URL(其实也不推荐这么做,除了URL有长度限制,把参数都直接暴露也不安全),那么就可以通过FlashMap来传递。只需要在重定向之前将要传递的数据写入请求(可以通过ServletRequestAttributes.getRequest()方法获得)的属性OUTPUT_FLASH_MAP_ATTRIBUTE中,这样在重定向之后的Handler中Spring就会自动将其设置到Model中,在显示订单信息的页面上就可以直接从Model中获得数据。
FlashMapManager就是用来管理FlashMap的。
Spring MVC九大组件的执行在DispatcherServlet的service()方法中完成。在这里,我重点介绍几个关键组件HandlerMapping、HandlerAdapter、ViewResolver在service()方法中的执行流程,具体调用分为以下几个步骤:
1、HandlerMapping回到调用HandlerAdapter
2、HandlerAdapter会返回ModelAndView
3、ModelAndView根据用户传入参数得到ViewResolvers
4、ViewResolvers会将用户传入的参数封装为View,交给引擎进行渲染。
下面给大家分享一张Spring MVC关键组件的执行流程图,以帮助大家更好地理解:
注意:上图中有大家最熟悉的两个类:ModelAndView和View类并不属于Spring MVC九大组件之列。
前面我们已经对Spring MVC的工作原理和源码进行了分析,在这个过程中有几个优化点。
1. Controller如果能保持单例模式,尽量使用单例模式
这样可以减小创建对象和回收对象的开销。也就是说,如果Controller的类变量和实例变量可以以方法形参声明就尽量以方法形参声明,不要以类变量和实例变量声明,这样可以避免线程安全问题。
2. 处理请求的方法中的形参务必加上@RequestParam注解
这样可以避免Spring MVC使用asm框架读取.class文件获取方法参数名。即便Spring MVC对读取出的方法参数名进行了缓存,如果能不读取.class文件当然更好。
先自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以扫码领取!
最后
在面试前我整理归纳了一些面试学习资料,文中结合我的朋友同学面试美团滴滴这类大厂的资料及案例
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
大家看完有什么不懂的可以在下方留言讨论也可以关注。
觉得文章对你有帮助的话记得关注我点个赞支持一下!
11459637718)]
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
大家看完有什么不懂的可以在下方留言讨论也可以关注。
觉得文章对你有帮助的话记得关注我点个赞支持一下!
需要更多Java资料的小伙伴可以帮忙点赞+关注,点击传送门,即可免费领取!