這篇文章,我們來看一下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
andRequestMappingHandlerMapping 。【關於這些類其他相關章節會單獨寫】。
- 它可以使用實現
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的一些主要的內容。其他細節可參考代碼。