1. 概述
在 《精尽 Spring MVC 源码分析 —— 容器的初始化(二)之 Servlet WebApplicationContext 容器》 一文中,我们看到,会调用 DispatcherServlet 的 #initStrategies(ApplicationContext context)
方法,初始化 Spring MVC 的各种组件。代码如下:
// DispatcherServlet.java |
- 掐指一算,一共有 9 个组件。本文,我们对这 9 个组件,做一个简单的介绍。
当然,在具体介绍组件之前,我们还是通过一张图,来看看这些组件,在一次用户的请求中,扮演了什么样的角色。
- 当然,这个图并没有包括所有的组件,主要涉及最核心的组件。😈
2. MultipartResolver
org.springframework.web.multipart.MultipartResolver
,内容类型( Content-Type
)为 multipart/*
的请求的解析器接口。
例如,文件上传请求,MultipartResolver 会将 HttpServletRequest 封装成 MultipartHttpServletRequest ,这样从 MultipartHttpServletRequest 中获得上传的文件。具体的使用示例,参见 《spring-boot 上传文件 MultiPartFile 获取不到文件问题解决》
关于内容类型( Content-Type
)为 multipart/*
,胖友可以看看 《HTTP 协议之 multipart/form-data 请求分析》 文章。
MultipartResolver 接口,代码如下:
// MultipartResolver.java |
3. LocaleResolver
org.springframework.web.servlet.LocaleResolver
,本地化( 国际化 )解析器接口。代码如下:
// LocaleResolver.java |
具体的使用示例,参见 《SpringMVC学习系列(8) 之 国际化》 。
4. ThemeResolver
org.springframework.web.servlet.ThemeResolver
,主题解析器接口。代码如下:
// ThemeResolver.java |
具体的使用示例,参见 《如何使用 Spring MVC 主题》 。
当然,因为现在的前端,基本和后端做了分离,所以这个功能已经越来越少用了。
5. HandlerMapping
org.springframework.web.servlet.HandlerMapping
,处理器匹配接口,根据请求( handler
)获得其的处理器( handler
)和拦截器们( HandlerInterceptor 数组 )。代码如下:
// HandlerMapping.java |
返回的对象类型是 HandlerExecutionChain ,它包含处理器(
handler
)和拦截器们( HandlerInterceptor 数组 )。简单代码如下:// HandlerExecutionChain.java
/**
* 处理器
*/
private final Object handler;
/**
* 拦截器数组
*/
private HandlerInterceptor[] interceptors;- 注意,处理器的类型可能和我们想的不太一样,是个 Object 类型。
6. HandlerAdapter
org.springframework.web.servlet.HandlerAdapter
,处理器适配器接口。代码如下:
// HandlerAdapter.java |
- 因为,处理器
handler
的类型是 Object 类型,需要有一个调用者来实现handler
是怎么被使用,怎么被执行。而 HandlerAdapter 的用途就在于此。可能如果接口名改成 HandlerInvoker ,笔者觉得会更好理解。 - 三个接口,代码比较好理解,胖友瞅一眼,就不细讲了。
7. HandlerExceptionResolver
org.springframework.web.servlet.HandlerExceptionResolver
,处理器异常解析器接口,将处理器( handler
)执行时发生的异常,解析( 转换 )成对应的 ModelAndView 结果。代码如下:
// HandlerExceptionResolver.java |
8. RequestToViewNameTranslator
org.springframework.web.servlet.RequestToViewNameTranslator
,请求到视图名的转换器接口。代码如下:
// RequestToViewNameTranslator.java |
粗略这么一看,有点不太好理解。捉摸了一下,还是放在后面一起讲解源码的时候,在详细讲解。
9. ViewResolver
org.springframework.web.servlet.ViewResolver
,实体解析器接口,根据视图名和国际化,获得最终的视图 View 对象。代码如下:
// ViewResolver.java |
ViewResolver 的实现类比较多,例如说,InternalResourceViewResolver 负责解析 JSP 视图,FreeMarkerViewResolver 负责解析 Freemarker 视图。当然,详细的,我们后续文章解析。
10. FlashMapManager
org.springframework.web.servlet.FlashMapManager
,FlashMap 管理器接口,负责重定向时,保存参数到临时存储中。代码如下:
// FlashMapManager.java |
默认情况下,这个临时存储会是 Session 。也就是说:
- 重定向前,保存参数到 Seesion 中。
- 重定向后,从 Session 中获得参数,并移除。
具体使用示例,参见 《Spring MVC Flash Attribute 的讲解与使用示例》 一文。
当然,实际场景下,使用的非常少,特别是前后端分离之后。
666. 彩蛋
小小水文一篇,先一起了解下 Spring MVC 的组件。酱紫,我们下一篇好整体的了解一个用户的请求,DispatcherServlet 是如何使用上述的组件,对其进行处理的。
参考和推荐如下文章:
- 田小波 《Spring MVC 原理探秘 - 一个请求的旅行过程》
- glmapper 《SpringMVC 源码系列:九大组件小记》
- 郝佳 《Spring 源码深度解析》 的 「11.3 DispatcherServlet」 小节
- 韩路彪 《看透 Spring MVC:源代码分析与实践》 的 「第9章 创建 Spring MVC 之器」 小节