Spring之MVC與Web環境

    Spring MVC是創建在IOC容器基礎上的。前端

   DispachServlet和ContextLoaderListener提供在Web容器中對Spring的接口,這些接口與Web容器耦合是經過ServletContext來實現,ServletContext爲Spring的IOC容器提供了一個宿主環境,Spring MVC創建起一個IOC容器體系。ContextLoaderListener定義爲監聽器,負責完成IOC容器在Web環境中的啓動工做。 DispatcherServlet起着分發請求的做用,定義了對應的URL映射。java

<servlet>
    <servlet-name>SpringDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>SpringDispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
 <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

IOC容器的啓動過程

     IOC容器的啓動過程就是創建上下文的過程,與ServletContext相伴而生。web

    spring使用默認的XmlWebApplicationContext做爲IOC容器。spring

ContextLoaderListener

    ContextLoaderListener的做用就是啓動啓動IOC容器並將其載入到WEB容器,是整個sping web應用加載IOC容器的第一個地方。它實現了ServletContextListener接口,提供了與servlet生命週期結合的回調(contextInitialized, contextDestroyed)。ContextLoaderListener啓動創建的上下文爲根上下文,DispatcherServlet所建立的上下文的的父上下文即爲此根上下文。具體的載入IOC容器的過程交由它的基類ContextLoader完成。設計模式

ContextLoader完成兩個IOC容器的創建,一個是在Web容器中創建雙親IOC容器,另外一個生成相應的WebApplicationContext並初始化。app

DispatcherServlet

    DispatcherServlet會創建本身的上下文持有Spring MVC的Bean對象,在創建本身持有的這個IOC容器的時候,會從ServletContext中獲得根上下文來做爲DispatcherServlet持有的上下文的雙親上下文。最後把本身的上下文保存到ServletContext中。框架

jsp

    DispacherServlet的工做主要分爲兩個部分:一是初始化部分,由initServletBean()啓動,經過initWebApplicationContext()最終調用DispatcherServlet的initStrategies()方法,對MVC模塊的其餘部分進行初始化(好比國際化、支持request映射的HandlerMapping等);另外一個是對HTTP請求進行相應,做爲Servlet,Web容器會調用Servlet的doGet()和doPost()方法,最終會調用DispatcherServlet的doService()方法,而後調用其封裝的doDispacher()方法。post

//MVC框架的初始化
protected void initStrategies(ApplicationContext context) {
    initMultipartResolver(context);
	initLocaleResolver(context);
	initThemeResolver(context);
	initHandlerMappings(context);
	initHandlerAdapters(context);
	initHandlerExceptionResolvers(context);
	initRequestToViewNameTranslator(context);
	initViewResolvers(context);
	initFlashMapManager(context);
}

MVC處理HTTP分發請求

在DispatcherServlet類的doService方法中,首先爲Request請求設置了一些對應的屬性實例,而後調用doDispatch方法去分發處理請求。如下是實際處理過程:url

1.在doDispatch方法中,調用checkMultipart方法去判斷該請求是不是Multipart請求(好比文件上傳),若是是,則使用MultipartResolver實例將請求轉換爲Multipart請求。

2.調用getHandler方法去獲取HandlerExecutionChain實例對象。在該方法中首先查找符合當前的HandlerMapping實例,而後調用HandlerMapping實例getHandler方法去獲取HandlerExecutionChain實例,該實例包裝了HandlerMapping實例對象,並在該實例中設置了相匹配的攔截器。

3.調用getHandlerAdapter方法,爲當前HandlerMapping實例查找對應的HandlerAdapter適配器實例。

4.調用HandlerExecutionChain實例的applyPreHandler方法,去調用其攔截器的preHandler方法(前置攔截方法)執行。若是返回true,則繼續日後處理,不然中止方法調用處理。(前置攔截方法執行調用)

5.調用HandlerAdapter適配器實例的handler方法去處理當前請求,並返回對應的ModelAndView對象。(調用目標對象的對應方法執行

6.調用HandlerExecutionChain實例的applyPostHandler方法,去調用其攔截器的postHandler方法(後置攔截方法)執行。(後置攔截方法執行調用

7.調用processDispatchResult方法去處理最後結果(ModelAndView或者異常),該方法調用render方法去渲染解析最後視圖。在render方法中首先經過ViewResolver解析器去獲取對應的視圖名稱的視圖View對象,最後在調用對應View對象的render方法渲染處理視圖,並響應對應結果給客戶端。(調用對應View渲染視圖

DispatcherServlet中使用的特殊的Bean

DispatcherServlet默認使用WebApplicationContext做爲上下文,所以咱們來看一下該上下文中有哪些特殊的Bean:

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

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

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

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

5、LocalResover本地化解析,由於Spring支持國際化,所以LocalResover解析客戶端的Locale信息從而方便進行國際化;

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

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

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

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

10FlashMapManager用於管理FlashMap的策略接口,FlashMap用於存儲一個請求的輸出,當進入另外一個請求時做爲該請求的輸入,一般用於重定向場景,後邊會細述。

相關文章
相關標籤/搜索