1. 程式人生 > >Spring MVC攔截器DispatcherServlet詳解

Spring MVC攔截器DispatcherServlet詳解

    前端控制器DispatcherServlet攔截請求之後做了什麼工作呢?DispatcherServlet又是如何分派請求的呢?

    我們來根據DispatcherServlet的原始碼分析一下,原始碼如下:

protected void initStrategies(ApplicationContext context) {

        // 初始化上傳檔案解析器
        initMultipartResolver(context);
        // 初始化本地化解析器
        initLocaleResolver(context);
        // 初始化主題解析器
initThemeResolver(context); // 初始化處理器騎射器,將請求對映到處理器 initHandlerMappings(context); // 初始化處理器介面卡 initHandlerAdapters(context); // 初始化處理器異常解析器,如果執行過程中遇到異常將交給HandlerExceptionResolver來解析 initHandlerExceptionResolvers(context); // 初始化請求到檢視名稱解析器 initRequestToViewNameTranslator(context)
; // 初始化檢視解析器,通過ViewResolver解析邏輯檢視名到具體檢視實現 initViewResolvers(context); // 初始化flash對映管理器 initFlashMapManager(context); }

    initStrategies方法將在WebApplicationContext初始化後自動執行,自動掃描上下文的Bean,根據名稱或型別匹配的機制查詢自定義的元件,如果沒有找到則會裝配一套Spring的預設元件。在`org.springframework.web.servlet` 路徑下有一個DispatcherServlet.properties配置檔案,該檔案指定了DispatcherServlet所使用的預設元件。

//本地化解析器
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
//主題解析器
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
//處理器對映器(共2個)
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
    org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
//處理器介面卡(共3個)
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
    org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
    org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
//異常處理器(共3個)
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
//FlashMap對映管理器
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

    如果開發者希望使用自定義型別的元件,則只需要在Spring配置檔案中配置自定義的Bean元件即可。Spring MVC如果發現上下文中有使用者自定義的元件,就不會使用預設的元件。

以下是DispatcherServlet裝配每種元件的細節。

本地化解析器。只允許一個例項

(1)查詢名為localeResolver、型別為.LocaleResolver的Bean作為該型別元件。

(2)如果沒有找到,則使用預設的實現類AcceptHeaderLocaleResolver作為該型別元件。

主題解析器。只允許一個例項。

(1)查詢名為themeResolver、型別為ThemeResolver的Bean作為該型別的元件。

(2)如果沒有找到,則使用預設的實現類FixedThemeResolver作為該型別元件。

處理器對映器。允許多個例項

(1)如果detectAllHandlerMappings的屬性為true(預設為true),則根據型別匹配機制查詢上下文以及Spring容器中所有型別為HandlerMapping的Bean,將它們作為該型別元件。

(2)如果detectAllHandlerMappings的屬性為fales,則查詢名為handlerMappings、型別為HandlerMapping的Bean作為該型別元件。

(3)如果通過以上兩種方式都沒有找到,則使用BeanNameUrlHandlerMapping實現類建立該型別的元件。

處理器介面卡。允許多個例項

(1)如果detectAllHandlerAdapters屬性為true(預設為true),則根據型別匹配機制查詢上下文以及Spring容器中所有型別為HandlerAdapter的Bean,將它們作為該型別元件。

(2)如果detectAllHandlerAdapters的屬性為false,則查詢名為handlerAdapter、型別為HandlerAdapter的Bean作為該型別元件。

(3)如果通過以上兩種方式都沒有找到,則使用DispatcherServlet.properties配置檔案中指定的三個實現類分別建立一個介面卡,並將其新增到介面卡列表中。

處理器異常解析器。允許多個例項

(1)如果detectAllHandlerExceptionResolvers的屬性為true(預設為true),則根據型別匹配機制查詢上下文以及Spring容器中所有型別為HandlerExceptionResolver的Bean,將它們作為該型別元件。

(2)如果detectAllHandlerExceptionResolver的屬性為false,則查詢名為handlerExceptionResolver、型別為HandlerExceptionResolver的Bean作為該型別元件。

(3)如果通過以上兩種方式都沒有找到,則查詢DispatcherServlet.properties配置檔案中定義的預設實現類,注意,該檔案中沒有對應處理器異常解析器的預設實現類,使用者可以自定義處理器異常解析器的實現類,將之新增到DispatcherServlet.properties配置檔案當中。

檢視名稱解析器。只允許一個例項

(1)查詢名為viewNameTranslator、型別為RequestToViewNameTranslator的Bean作為該型別元件。

(2)如果沒有找到,則使用預設的實現DefaultRequestToViewNameTranslator作為該型別的元件。

檢視解析器。允許多個例項

(1)如果detectAllViewResolver的屬性為true(預設為true),則根據型別匹配機制查詢上下文以及Spring容器中所有型別為ViewResolver的Bean,將它們作為該型別元件。

(2)如果detectAllViewResolver的屬性為false,則查詢名為viewResolvers、型別為ViewResolver的Bean作為該型別元件。

(3)如果通過以上兩種方式都沒有找到,則查詢DispatcherServlet.properties配置檔案中定義的預設實現類InternalResolverViewResolver作為該型別的元件。

檔案上傳解析器。只允許一個例項

(1)查詢名為muliipartResolver、型別為MuliipartResolver的Bean作為該型別元件。

(2)如果使用者沒有在上下文中顯式定義MuliipartResolver型別的自己,則DispatcherServlet將不會載入該型別的元件。

FlashMap對映管理器。

(1)查詢名為FlashMapManager、型別為SessionFlashMapManager的Bean作為該型別元件,用於管理FlashMap,即資料預設儲存在HttpSession中。

    如果同一型別的元件存在多個,那麼它們之間的優先順序順序如何確定呢?因為這些元件都實現了org.springFramework.core.Ordered介面,所以可以通過Order屬性確定優先順序的順序,值越小的優先順序越高。