文章目錄
1 SpringMVC簡介
spring框架提供了構建Web應用程序的全功能MVC模塊。通過策略接口,Spring框架是高度可配置的,而且支持多種視圖技術。SpringMVC通過實現了Servlet接口的DispatcherServlet來封裝核心功能的實現,具有處理程序映射,視圖解析,主題解析等核心功能。
SpringMVC主要解決了以下三個問題 :
- 將web頁面的請求傳給服務器
- 根據不同的請求處理不同的邏輯單元
- 返回處理結果並跳轉至響應頁面
2 一次SpringMVC的請求的處理路徑
當瀏覽器發送一次請求到達SpringMVC的核心處理器DispatcherServlet之後,會經歷很多次邏輯的封裝,在每一段都會留下一些信息同時帶走一部分信息。一次SpringMVC請求所經歷的流程大致如下圖所示:
- 請求的第一站是Spring的DispatcherServlet。SpringMVC的所有請求都會通過一個前端控制器Servlet。前端控制器是常用的Web應用程序模式,在這裏一個單實例的Servelt將請求委託給應用程序的其他組件來執行實際的處理。在SpringMVC中,DispatcherServlet就承擔了這個責任。DispatcherServlet的任務就是將請求發送給controller,控制器是一個用於處理請求的Spring組件。
- 請求的第二站是處理器映射,DispatcherServlet通過查詢一個或者多個處理器映射(handler mapping)。處理器映射會根據請求所攜帶的URL信息進行決策。
- 請求的第三站是控制器。DispatcherServlet帶着映射器所返回的控制器信息將請求發送給選中的控制器,到了控制器這一層,請求會將用戶所提交的信息交給控制器來進行邏輯的處理。完成邏輯處理後,控制器會將產生的信息返回給用戶並在瀏覽器上面展示。
- 請求的第四步是 控制器將數據連同視圖名稱一起返回給DispatcherServlet。通過這樣的方式來進行視圖與控制器之間的解耦,傳遞給DispatcherServlet的視圖名稱並不能代表某一個特定的頁面。
- 請求的第五步是 DispatcherServlet通過視圖解析器來將邏輯視圖名匹配爲一個特定的視圖實現。
- 請求的第六步是視圖的實現
- 最後響應到頁面進行輸出。
3 DisPatcherServlet 初始化
我們簡單介紹一個DisPatcherServlet,DisPatcherServlet是Servlet接口的實現類。Servlet是一個java編寫的程序,基於HTTP協議。在服務器端運行,按照Servlet規範編寫的一個Java類。主要是處理客戶端請求並將結果發送到客戶端。
3.1 servlet生命週期
- 初始化階段 servlet容器加載servlet類並且把servlet類的.class文件中的數據讀到內存中。servlet容器創建一個ServletConfig對象,ServletConfig對象包含了servlet的初始化配置信息。servlet容器創建一個servlet對象,調用servlet對象的init方法進行初始化。
- 運行階段 servlet容器接收到一個請求時,servlet容器會針對這個請求創建servletRequest對象和servletResponse對象。然後調用service方法。並把這兩個參數傳遞給service方法,service方法通過servletRequest對象獲得請求的信息。處理該請求,再通過servletResponse對象生成這個請求的響應結果。然後銷燬servletRequest和servletResponse對象。
- 銷燬階段 當web應用被終止時,servlet容器會先調用servlet對象的destory方法,然後再銷燬servlet對象,同時也會銷燬與servlet對象關聯的servletConfig對象。我們可以在destory方法的實現中,釋放servlet所佔用的資源。
3.2 DispatcherServlet初始化
DispatcherServlet的父類HttpServletBean重寫了init方法,主要是將servlet實例轉換爲BeanWrapper類型的實例,以便使用Spring中提供的注入功能進行對應屬性的注入。init方法主要執行了以下幾步
- 封裝及驗證初始化參數
- 將當前servlet實例轉換成BeanWrapper實例
- 註冊相對於Resource的屬性編輯器
- 屬性注入
- servletBean的初始化
3.3 WebApplicationContext初始化
servletBean將自己關鍵的初始化邏輯的實現委託給了initWebApplication(),這個方法的主要工作就是創建或刷新WebApplicationContext實例並對servlet功能所使用的變量進行初始化,這個方法主要執行了以下幾步
-
尋找或創建對應的WebApplicationContext實例
- 通過構造函數的注入進行初始化
- 通過contextAttribute進行初始化
- 重新創建WebApplicationContext實例
-
我們會發現最後都調用了configureAndRefreshWebApplicationContext方法 這個方法最後又都指向了ConfigureAndRefreshWebApplication 的 refresh方法。
-
refresh方法代碼如下 :
- 初始化MultipartResolver 用來文件上傳
- 初始化LocaleResolver 國際化參數配置
- 初始化ThemeResolver 主題解析器
- 初始化HandlerMapping 映射器
- 初始化HandlerAdapters 適配器
- 初始化RequestToViewNameTranslator 進行視圖匹配的對象
- 初始化ViewResolvers ViewResolver接口定義了resolverViewName方法,根據ViewName創建合適類型的View實現。