詳解Spring MVC中的DispatcherServlet丨乾貨
Spring MVC 4與其它MVC框架類似,都是基於請求驅動的,通過中央Servlet處理器,將請求轉發到控制器然後完成相應的功能。Spring的 DispatcherServlet與其它MVC框架不同的是,它與Spring的IoC容器整合並允許使用者使用Spring的其它特性。
1. DispatcherServlet的作用
Spring MVC 4的工作流如下圖所示。DispatcherServlet充當了“前端控制器”的角色。

DispatcherServlet實際上就是一個Servlet,它繼承了HttpServlet,在使用前必須在 web.xml 中進行宣告,按照 DispatcherServlet需要處理的請求配置 url 對映,宣告格式如下:
<web-app> <servlet> <servlet-name>favsoft</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>favsoft</servlet-name> <url-pattern>/favsoft/*</url-pattern> </servlet-mapping></web-app>
假設我們按照上面的 DispatcherServlet ,那麼在請求的URL中,所有以 /favsoft 為開頭的請求都將被 DispatcherServlet 例項進行轉發。在 Servlet 3.0以後的環境中,也可以程式設計式方式配置Servlet容器,如下圖所示,它相當於web.xml中配置的程式碼。
public class MyWebApplicationInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext container) { ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet()); registration.setLoadOnStartup(1); registration.addMapping("/favsoft/*"); } }
WebApplicationInitializer 是Spring MVC提供的一個介面,用來識別程式碼中的配置,並初始化Servlet容器。AbstractDispatcherServletInitializer 抽象類實現了該介面,使得該類通過servlet對映就註冊到 DispatcherServlet中。
在Spring MVC框架中,每一個DispatcherServlet都有它的 WebApplicationContext上下文,這些上下文繼承了 WebApplicationContext根上下文中的所有類(Java Beans),這些繼承的類(Java Beans)能夠在特定的servlet作用域中被重寫,也可以定義新的作用域的類例項。
2. 預設的DispatcherServlet配置
DispatcherServlet 的預設情況下,是按照 org.springframework.web.servlet 下面的 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
3. DispatcherServlet的工作流程
當我們配置好 DispatcherServlet 之後,一個特定的 DispatcherServlet 請求過來之後,它的工作流程如下:
(1)WebApplicationContext 上下文尋求並繫結控制器和 ,預設情況下會繫結 DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE下的預設值。
(2)語言解析器繫結到請求啟動過程中的元素來解決所使用的語言環境處理請求(渲染檢視、準備資料等),如果不需要處理國際化,就不需要這步。
(3)主題解析器繫結請求讓檢視這樣的元素知道需要使用哪種主題,如果沒有使用主題,同樣忽略此步驟。
(4)如果指定一個多檔案解析器,請求就會檢查這些檔案,如果找到這些檔案,請求就會被包裝到 MultipartHttpServletRequest中,進一步處理其他元素。
(5)接下來,尋找一個合適的處理器,如果找到了,處理器相關執行鏈就會執行,為資料模型或渲染檢視做準備。
(6)如果返回了模型,就會渲染檢視。如果沒有返回模型(可能是為了安全考慮,預處理或後處理程式攔截了請求),就不需要渲染檢視,請求可能已經完成了。
在處理請求過程中,如果發生了異常,就會被 WebApplicationContext 上下文中的異常處理器捕獲到並丟擲。當然,異常處理器允許我們通過一些自定義的行為處理異常。
Spring DispatcherServlet也支援返回最近修改日期: DispatcherServlet 尋找合適的處理器並測試處理器是否實現了最近更新介面,如果通過的話, LashModified介面就會返回 long 型別的值到客戶端。
寫在最後:歡迎留言討論,加關注,持續更新!