Spring MVC 4與其它MVC框架類似轮蜕,都是基于請求驅動的秆撮,通過中央Servlet處理器,將請求轉發(fā)到控制器然后完成相應的功能奴愉。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 實例進行轉發(fā)烫止。在 Servlet 3.0以后的環(huán)境中,也可以編程式方式配置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 抽象類實現(xiàn)了該接口颂郎,使得該類通過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)語言解析器綁定到請求啟動過程中的元素來解決所使用的語言環(huán)境處理請求(渲染視圖急膀、準備數(shù)據(jù)等)沮协,如果不需要處理國際化,就不需要這步卓嫂。
(3)主題解析器綁定請求讓視圖這樣的元素知道需要使用哪種主題慷暂,如果沒有使用主題,同樣忽略此步驟命黔。
(4)如果指定一個多文件解析器呜呐,請求就會檢查這些文件,如果找到這些文件悍募,請求就會被包裝到 MultipartHttpServletRequest中蘑辑,進一步處理其他元素。
(5)接下來坠宴,尋找一個合適的處理器洋魂,如果找到了,處理器相關執(zhí)行鏈就會執(zhí)行喜鼓,為數(shù)據(jù)模型或渲染視圖做準備副砍。
(6)如果返回了模型,就會渲染視圖庄岖。如果沒有返回模型(可能是為了安全考慮豁翎,預處理或后處理程序攔截了請求),就不需要渲染視圖隅忿,請求可能已經(jīng)完成了心剥。
在處理請求過程中,如果發(fā)生了異常背桐,就會被 WebApplicationContext 上下文中的異常處理器捕獲到并拋出优烧。當然,異常處理器允許我們通過一些自定義的行為處理異常链峭。
Spring DispatcherServlet也支持返回最近修改日期: DispatcherServlet 尋找合適的處理器并測試處理器是否實現(xiàn)了最近更新接口畦娄,如果通過的話, LashModified接口就會返回 long 類型的值到客戶端弊仪。
Java高架構師熙卡、分布式架構、高可擴展励饵、高性能再膳、高并發(fā)、性能優(yōu)化曲横、Spring boot喂柒、Redis不瓶、ActiveMQ、Nginx灾杰、Mycat蚊丐、Netty、Jvm大型分布式項目實戰(zhàn)學習架構師視頻免費獲取架構群:854180697????????加群鏈接
寫在最后:歡迎留言討論艳吠,加關注麦备,持續(xù)更新!