ContextLoaderListener和Spring MVC中的DispatcherServlet學習

DispatcherServlet介紹

DispatcherServlet是Spring前端控制器的實現,提供Spring Web MVC的集中訪問點,並且負責職責的分派,與Spring IoC容器無縫集成,從而可以獲得Spring的所有好處。

DispatcherServlet主要用作職責調度工作,本身主要用於控制流程,主要職責如下:

1、文件上傳解析,如果請求類型是multipart將通過MultipartResolver進行文件上傳解析;
2、通過HandlerMapping,將請求映射到處理器(返回一個HandlerExecutionChain,它包括一個處理器、多個HandlerInterceptor攔截器);
3、通過HandlerAdapter支持多種類型的處理器(HandlerExecutionChain中的處理器);
4、通過ViewResolver解析邏輯視圖名到具體視圖實現;
5、本地化解析;
6、渲染具體的視圖等;
7、如果執行過程中遇到異常將交給HandlerExceptionResolver來解析。

 

DispatcherServlet默認使用WebApplicationContext作爲上下文,Spring默認配置文件爲“/WEB-INF/[servlet名字]-servlet.xml”。

DispatcherServlet也可以配置自己的初始化參數,覆蓋默認配置:

參數

描述

contextClass

實現WebApplicationContext接口的類,當前的servlet用它來創建上下文。如果這個參數沒有指定, 默認使用XmlWebApplicationContext。

contextConfigLocation

傳給上下文實例(由contextClass指定)的字符串,用來指定上下文的位置。這個字符串可以被分成多個字符串(使用逗號作爲分隔符) 來支持多個上下文(在多上下文的情況下,如果同一個bean被定義兩次,後面一個優先)。
默認爲/WEB-INF/[server-name]-servlet.xml

namespace

WebApplicationContext命名空間。默認值是[server-name]-servlet。

如下:

<servlet>
        <servlet-name>demo</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-servlet-config.xml</param-value>
        </init-param>
</servlet>
<servlet-mapping>
        <servlet-name>demo</servlet-name>
        <url-pattern>/</url-pattern>
</servlet-mapping>

 

Servlet上下文關係

DispatcherServlet的上下文是通過配置servlet的contextConfigLocation來加載的,默認實現是XmlWebApplicationContext。

值得注意的是DispatcherServlet的上下文僅僅是Spring MVC的上下文,而Spring加載的上下文是通過ContextLoaderListener來加載的。一般spring web項目中同時會使用這兩種上下文,前者僅負責MVC相關bean的配置管理(如ViewResolver、Controller、MultipartResolver等),後者則負責整個spring相關bean的配置管理(如相關Service、DAO等)。

因此在/WEB-INF/[server-name]-servlet.xml中配置的Bean一般只針對Spring MVC有效,而在ContextLoaderListener配置文件下配置的bean則對整個spring有效。

上下文創建完後會放在ServletContext對象中,其中ContextLoaderListener加載的上下文放在ServletContext的key爲WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE屬性中,而DispatcherServlet加載的上下文在每次請求時會放一份在request對象的key爲WEB_APPLICATION_CONTEXT_ATTRIBUTE屬性中。因而兩者的獲取方式也不一樣,前者可以通過WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)或WebApplicationContextUtils.getWebApplicationContext(servletContext)或WebApplicationContextUtils.getWebApplicationContext(servletContext,attrname)方法來獲取對應的applicationContext,而後者則通過RequestContextUtils.getWebApplicationContext(request)或 WebApplicationContextUtils.getWebApplicationContext(servletContext,attrname)方法來獲取對應的applicationContext。
注:對於ContextLoaderListener加載的上下文,attrname即上面提到的WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;而對於DispatcherServlet中的上下文則爲FrameworkServlet.class.getName() + ".CONTEXT." + getServletName()

 

通過上下文所在的屬性可以看出,如果通過WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)來試圖獲取DispatcherServlet加載的applicationContext時,就會拋出"No WebApplicationContext found: no ContextLoaderListener registered?"的異常。

 

DispatcherServlet中使用的特殊的Bean

DispatcherServlet默認使用WebApplicationContext作爲上下文,因此我們來看一下該上下文中有哪些特殊的Bean:

1、Controller:處理器/頁面控制器,做的是MVC中的C的事情,但控制邏輯轉移到前端控制器了,用於對請求進行處理;

2、HandlerMapping:請求到處理器的映射,如果映射成功返回一個HandlerExecutionChain對象(包含一個Handler處理器(頁面控制器)對象、多個HandlerInterceptor攔截器)對象;如BeanNameUrlHandlerMapping將URL與Bean名字映射,映射成功的Bean就是此處的處理器;

3、HandlerAdapter:HandlerAdapter將會把處理器包裝爲適配器,從而支持多種類型的處理器,即適配器設計模式的應用,從而很容易支持很多類型的處理器;如SimpleControllerHandlerAdapter將對實現了Controller接口的Bean進行適配,並且掉處理器的handleRequest方法進行功能處理;

4、ViewResolver:ViewResolver將把邏輯視圖名解析爲具體的View,通過這種策略模式,很容易更換其他視圖技術;如InternalResourceViewResolver將邏輯視圖名映射爲jsp視圖;

5、LocalResover:本地化解析,因爲Spring支持國際化,因此LocalResover解析客戶端的Locale信息從而方便進行國際化;

6、ThemeResovler:主題解析,通過它來實現一個頁面多套風格,即常見的類似於軟件皮膚效果;

7、MultipartResolver:文件上傳解析,用於支持文件上傳;

8、HandlerExceptionResolver:處理器異常解析,可以將異常映射到相應的統一錯誤界面,從而顯示用戶友好的界面(而不是給用戶看到具體的錯誤信息);

9、RequestToViewNameTranslator:當處理器沒有返回邏輯視圖名等相關信息時,自動將請求URL映射爲邏輯視圖名;

10、FlashMapManager:用於管理FlashMap的策略接口,FlashMap用於存儲一個請求的輸出,當進入另一個請求時作爲該請求的輸入,通常用於重定向場景
 

通過以上的bean可以看出,一般LocalResover、ViewResolver等需要配置在/WEB-INF/[server-name]-servlet.xml文件中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章