这篇文章,我们来看一下spring-webmvc-***.RELEASE.jar中的servlet包下的几个类,如下图:
- DispatcherServlet.class
- DispatcherServlet.properties
当工程启动解析完spring-mvc.xml中mvc相关的标签后,便会来到DispatcherServlet类
首先根据百度翻译,看一下Dispatcher的翻译
Dispatcher | |
英[dɪˈspætʃə(r)] | 美[dɪˈspætʃər] |
n. | (火车、汽车、飞机等的) 调度员; (应急车辆的) 调度员; |
那么顾名思义DispatcherServlet就是用来调度我们Servlet请求的,先看一下官方api说明:
Central dispatcher for HTTP request handlers/controllers, e.g. for web UI controllers or HTTP-based remote service exporters. Dispatches to registered handlers for processing a web request, providing convenient mapping and exception handling facilities.
它是一个中央调度器,他可以把request请求分发给一个已经注册的handler来处理这个请求。
DispatcherServlet个类十分灵活,它具有以下功能
- 它基于JavaBeans配置机制
- 它可以使用你实现HandlerMapping接口的类(用于指定某个请求会被哪个handler类处理),来实现一套自定义的映射处理器。默认使用的是 BeanNameUrlHandlerMapping and
RequestMappingHandlerMapping 。【关于这些类其他相关章节会单独写】。
- 它可以使用实现
HandlerAdapter接口的类。默认使用是
HttpRequestHandlerAdapter和SimpleControllerHandlerAdapter - 它可以使用通过实现
HandlerExceptionResolver接口的类,来处理异常。默认
使用的是
ExceptionHandlerExceptionResolver,ResponseStatusExceptionResolver和
DefaultHandlerExceptionResolver - 它可以使用通过实现
ViewResolver接口的类,来指定视图解析器。默认
使用的是
InternalResourceViewResolver - 如果没有指定视图名,那么它会使用一个实现
RequestToViewNameTranslator接口的类,默认
使用的是
DefaultRequestToViewNameTranslator - 它可以使用通过实现
MultipartResolver接口的类,来处理上传文件的功能,默认
使用的是
CommonsMultipartResolver - 他还可以通过实现
LocaleResolver接口的类,来处理本地化操作。默认
使用的是
AcceptHeaderLocaleResolver - 它还支持通过实现
ThemeResolver接口,来实现自定义的主题,默认使用的是
FixedThemeResolver.
注意看,上面的所说的实现类,都会在initStrategies方法中进行注册。如下图
但是如果找不到自定义的实现类,那么这些init方法中便会创建上面所说的默认类。这些默认类就是在DispatcherServlet.properties文件中指定的了。这就是DispatcherServlet和DispatcherServlet.properties的关系。
DispatcherServlet.properties中设置的默认类在程序启动时,会通过DispatcherServlet静态块保存起来,如下:
private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";
private static final Properties defaultStrategies;
static {
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());
}
}
DispatcherServlet.properties中的内容如下:
# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
然后,如果在init***方法中,找不到自定义的实现类(这个实现类应该在spring-mvc.xml中通过bean来定义),便会抛出异常,然后在catch中创建默认的类,这里以initLocaleResolver(context);为例,如下图:
代码this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);表示从context中找获取实现LocaleResolver接口的类,如果找不到,则会在catch中创建默认类(DispatcherServlet.properties中=号左侧LocaleResolver对应的那个类就是默认的类)。
例如,我在spring-mvc.xml中定义了一个实现了ThemeResolver的类,那么就会使用我自定义的这个类,如下:
然后我们可以看到,这里程序在启动时,就会从容器中把实现了ThemeResolver的MyThemeResolver取出来,然后使用这个类,而不会在使用默认类了
以上便是DispatcherServlet和DispatcherServlet.properties的一些主要的内容。其他细节可参考代码。