2.4 详解DispatcherServlet
2.4 详解DispatcherServlet
2.3节中的第一个Spring MVC
应用已经成功运行了。那么,前端控制器DispatcherServlet
截获请求后做了什么工作呢? DispatcherServlet
又是如何分派请求的呢?
initStrategies方法
分析DispatcherServlet
的源代码如下:
1 | protected void initStrategies(ApplicationContext context) { |
如何下载Spring源码
提示:org/Springframework/web/Servlet/DispatcherServlet
是Spring
框架的源代码,读者可在配套资源中找到Spring
源代码。
GitHub下载Spring源码
- 到GitHub上上下载你想要的版本的zip文件,
- 解压.
- 依次进入路径:即可找到
1
spring-webmvc\src\main\java\org\springframework\web\servlet\
DispatcherServlet
的源码
例如,我电脑上的DispatcherServlet
路径为:1
G:\Desktop\随书源码\库文件2\spring-framework-5.2.1.RELEASE\spring-webmvc\src\main\java\org\springframework\web\servlet\DispatcherServlet.java
initstrategies
方法将在WebApplicationContext
初始化后自动执行,自动扫描上下文的Bean
,根据名称或类型匹配的机制査找自定义的组件,如果没有找到则会装配套Spring
的默认组件。自定义组件
如果开发者希望使用自定义类型的组件,则只需要在Spring
配置文件中配置自定义的Bean
组件即可。Spring MVC
如果发现上下文中有用户自定义的组件,就不会使用默认的组件。DispatcherServlet装配每种组件的细节
以下是DispatcherServlet
装配每种组件的细节。本地化解析器
本地化解析器。只允许一个实例
- 查找名为
localeResolver
、类型为.LocaleResolver
的Bean
作为该类型组件。 - 如果没有找到,则使用默认的实现类
AcceptHeaderLocaleResolver
作为该类型组件。
主题解析器
主题解析器。只允许一个实例
- 查找名为
themeResolver
、类型为ThemeResolver
的Bean
作为该类型组件。 - 如果没有找到,则使用默认的实现类
FixedThemeResolve
作为该类型组件。
处理器映射器
处理器映射器。允许多个实例
- 如果
detectAllHandlerMappings
的属性为true
(默认为true
),则根据类型匹配机制查找上下文以及Spring
容器中所有类型为HandlerMapping
的Bean
,将它们作为该类型组件。 - 如果
detectAllHandlerMappings
的属性为false
,则查找名为handlerMapping
,类型为HandlerMapping
的Bean
作为该类型组件。 - 如果通过以上两种方式都没有找到,则使用
BeanNameUrLHandlerMapping
实现类创建该类型的组件。
处理器适配器
处理器适配器。允许多个实例
- 如果
detectAllHandlerAdapters
的属性为true
(默认为true
),则根据类型匹配机制查找上下文以及Spring
容器中所有类型为HandlerAdapter
的Bean
,将它们作为该类型组件。 - 如果
detectAllHandlerAdapters
的属性为false
,则查找名为handlerAdapter
、类型为HandlerAdapter
的Bean
作为该类型组件。 - 如果通过以上两种方式都没有找到,则使用
DispatcherServlet.properties
配置文件中指定的三个实现类分别创建一个适配器,并将其添加到适配器列表中。
视图解析器
视图解析器。允许多个实例
- 如果
detectAllViewResolvers
的属性为true
(默认为true
),则根据类型匹配机制查找上下文以及Spring
容器中所有类型为ViewResolver
的Bean
,将它们作为该类型组件。 - 如果
detectAllViewResolvers
的属性为false
,则查找名为viewResolvers
、类型为ViewResolver
的Bean
作为该类型组件。 - 如果通过以上两种方式都没有找到,则查找
DispatcherServlet.properties
配置文件中定义的默认实现类InternalResourceViewResolver
作为该类型的组件。
文件上传解析器
文件上传解析器。只允许一个实例
- 查找名为
muliipartResolver
、类型为MuliipartResolver
的Bean
作为该类型组件。 - 如果用户没有在上下文中显式定义MuliipartResolver类型的组件,则DispatcherServlet将不会加载该类型的组件。
FlashMap映射管理器
FlashMap映射管理器。
- 查找名为
FlashMapManager
、类型为SessionFlashMapManager
的Bean
作为该类型组件,用于管理FlashMap
,即数据默认存储在HttpSession
中。
小结
DispatcherServlet
装配的各种组件,
- 有些只允许一个实例,比如文件上传解析器
MuliipartResolver
、本地化解析器LocaleResolver
等; - 有些则允许多个实例,如处理器映射器
HandlerMapping
、处理器适配器HandlerAdapter
等,
读者需要注意这一点。
如果同一类型的组件存在多个,那么它们之间的优先级顺序如何确定呢?因为这些组件都实现了org.springframework.core.Ordered
接口,所以可以通过Order
属性确定优先级的顺序,值越小的优先级越高。