HandlerMapping
HandlerMapping是用来查找Handler 的,也就是处理器,具体的表现形式可以是类,也可以是方法。比如,标注了@RequestMapping的每个方法都可以看成一个 Handler。Handler 负责实际的请求处理,在请求到达后,HandlerMapping的作用便是找到请求相应的处理器Handler和Interceptor.
HandlerAdapter
从名字上看,HandlerAdapter 是一个适配器。因为Spring MVC中Handler 可以是任意形式的,只要能够处理请求便可。但是把请求交给Servlet 的时候,由于Servlet 的方法结构都是
doService(HttpServletRequest req, HttpServletResponse resp)形式的,要让固定的Servlet 处理方法调用Handler来进行处理,这一步 工作便是HandlerAdapter要做的事。
小结:Handler是用来干活的工具;HandlerMapping用于根据需要干的活找到相应的工具;HandlerAdapter是使用工具干活的人
HandlerExceptionResolver
其它组件都是用来干活的。在干活的过程中难免会出现问题,出问题后怎么办呢?这就需要有一个专门的角色对异常情况进行处理,在SpringMVC中就是HandlerExceptionResolver。
HandlerExceptionResolver 是用来处理Handler 产生的异常情况的组件。具体来说,此组件的作用是根据异常设置ModelAndView, 之后交给渲染方法进行渲染,渲染方法会将ModelAndView渲染成页面。
不过要注意,HandlerExceptionResolver 只用于解析对请求做处理阶段产生的异常,渲染阶段的异常不归它管,这也是SpringMVC组件设计的一大原则一分工明确、互不干涉。
ViewResolver
ViewResolver 的主要作用是将String 类型的视图名和Locale解析为View 类型的视图,只有一个resolveViewName()方法。从方法的定义可以看出,Controller层返回的String 类型的视图名viewName最终会在这里被解析成为View。
View 是用来渲染页面的,也就是说,它会将程序返回的参数和数据填入模板中,生成HTML文件。ViewResolver在这个过程中主要做两件大事: ViewResolver 会找到渲染所用的模板(第一件大事)和所用的技术(第二件大事,其实也就是找到视图的类型,如JSP)并填入参数。
默认情况下,Spring MVC会为我们自动配置一个InternalResourceViewResolver,是针对JSP类型视图的。
RequestToViewName Translator
RequestToViewNameTranslator组件的作用是从请求中获取ViewName。因为ViewResolver根据ViewName查找View,但有的Handler处理完成之后,没有设置View,也没有设置ViewName,
便要通过这个组件来从请求中查找ViewName。
RequestToViewNameTranslator在Spring MVC容器里只可以配置一个,所以所有request到ViewName的转换规则都要在一个Translator里面全部实现。
LocaleResolver
解析视图需要两个参数:一是视图名,另一个是Locale。视图名是处理器返回的,Locale是从哪里来的?这就是LocaleResolver要做的事情。LocaleResolver用于从request解析出Locale,Locale就是zh-cn之类,表示一个区域,有了这个就可以对不同区域的用户显示不同的结果。
SpringMVC主要有两个地方用到了Locale:一是ViewResolver视图解析的时候;二是用到国际化资源或者主题的时候。
ThemeResolver
用于解析主题。SpringMVC中一个主题对应一个properties文件,里面存放着跟当前主题相关的所有资源、如图片、css样式等。
SpringMVC的主题也支持国际化,同一个主题不同区域也可以显示不同的风格。SpringMVC中跟主题相关的类有 ThemeResolver、ThemeSource和Theme。主题是通过一系列资源来具体体现的,要得到一个主题的资源,首先要得到资源的名称,这是ThemeResolver的工作。然后通过主题名称找到对应的主题(可以理解为一个配置)文件,其抽象也就是Theme,这是ThemeSource的工作。最后从主题中通过Theme来获取主题和具体的资源。
MultipartResolver
用于处理上传请求。处理方法是将普通的request包装成MultipartHttpServletRequest,后者可以直接调用getFile方法获取File,如果上传多个文件,还可以调用getFileMap得到FileName->File结构的Map。此组件中一共有三个方法,作用分别是判断是不是上传请求,将request包装成MultipartHttpServletRequest、处理完后清理上传过程中产生的临时资源。
FlashMapManager
说到FlashMapManager组件,得先说一下FlashMap。
FlashMap用于重定向时的参数传递,比如在处理用户订单时,为了避免重复提交,可以处理完post请求后重定向到一个get请求,这个get请求可以用来显示订单详情之类的信息。这样做虽然可以规避用户重新提交订单的问题,但是在这个页面上要显示订单的信息,这些数据从哪里获取呢?因为重定向是没有传递参数这一功能的,如果不想把参数写进URL(其实也不推荐这么做,除了URL有长度限制,把参数都直接暴露也不安全),那么就可以通过FlashMap来传递。只需要在重定向之前将要传递的数据写入请求(可以通过ServletRequesttributes getRequest(方法获得)的属性OUTPUT_ FLASH_ MAP ATTRIBUTE中,这样在重定向之后的Handler中Spring就会自动将其设置到Model中,在显示订单信息的页面上就可以直接从Model中获得数据。
FlashMapManager就是用来管理FlashMap的。
总结
通过对此9大组件的宏观认识,对分析SpringMVC的设计、原理与实现都会有很大的帮助作用。
参考
(1)https://www.cnblogs.com/wkcto/p/13827331.html
(2)https://blog.youkuaiyun.com/Apeopl/article/details/84372771
(3)《Spring5核心原理与30个类手写实战》