SpringMVC 工作原理
SpringMVC 是 Spring 框架中用于構建 Web 應用的核心模塊,其工作流程圍繞 “前端控制器(DispatcherServlet)” 展開,通過組件間的協作完成請求處理與響應。理解其工作原理是掌握 SpringMVC 開發的關鍵,以下將通過 核心組件解析、詳細工作流程(含步驟拆解與流程圖解) 兩部分進行說明。
SpringMVC 核心組件
在了解流程前,需先明確參與請求處理的核心組件及其職責,各組件通過 Spring 容器管理,由 DispatcherServlet 調度。
組件名稱 | 核心職責 |
---|---|
DispatcherServlet | 前端控制器(核心),統一接收所有請求,協調其他組件完成處理,避免組件耦合。 |
HandlerMapping | 處理器映射器,根據請求 URL 找到對應的 Handler(處理器,如 Controller 方法),返回 Handler 及攔截器鏈。 |
HandlerAdapter | 處理器適配器,適配不同類型的 Handler(如注解式 Controller、XML 配置的 Controller),調用 Handler 的業務方法。 |
Handler(處理器) | 業務邏輯處理器,即開發者編寫的 Controller 類(或方法),負責處理具體業務邏輯。 |
ModelAndView | 處理器返回的結果對象,包含 Model(數據模型,如請求處理后的業務數據) 和 View(視圖名稱,如 JSP 路徑)。 |
ViewResolver | 視圖解析器,根據 ModelAndView 中的視圖名稱,解析為實際的 View 視圖對象(如 JSP 文件、HTML 頁面)。 |
View(視圖) | 渲染視圖,將 Model 中的數據填充到視圖模板(如 JSP),生成最終的 HTML 響應給客戶端。 |
Interceptor | 攔截器,可在請求處理的 預處理(前)、后處理(后)、完成處理(最終) 階段插入自定義邏輯(如登錄校驗、日志記錄)。 |
SpringMVC 完整工作流程(10 步拆解)
SpringMVC 的工作流程本質是 “DispatcherServlet 主導的組件協作流程”,從客戶端發送請求到接收響應,共分為 10 個核心步驟,流程如下:
1. 流程步驟拆解
- 客戶端發送 HTTP 請求
用戶通過瀏覽器、Postman 等工具發送請求(如http://localhost:8080/springmvc/user/list
),請求被 Web 服務器(如 Tomcat)接收。 - 請求被 DispatcherServlet 攔截
Web 服務器根據web.xml
(或 SpringBoot 自動配置)中配置的DispatcherServlet
映射規則(如/
攔截所有請求,排除靜態資源),將請求轉發給 DispatcherServlet(前端控制器)。 - DispatcherServlet 調用 HandlerMapping
DispatcherServlet 不直接處理請求,而是調用 HandlerMapping(處理器映射器),根據請求 URL、請求方法(GET/POST)等信息,查找對應的 Handler(如 Controller 中的listUser()
方法),同時返回該 Handler 對應的 攔截器鏈(Interceptor Chain)。 - DispatcherServlet 獲取 HandlerAdapter
DispatcherServlet 根據 Handler 的類型(如注解式@Controller
、實現Controller
接口的類),調用對應的 HandlerAdapter(處理器適配器),確保后續能統一調用 Handler 的業務方法。 - 執行攔截器的預處理方法(preHandle)
若存在攔截器,DispatcherServlet 會先執行攔截器鏈中所有攔截器的preHandle()
方法。- 若任意一個攔截器的
preHandle()
返回false
,則請求終止,直接返回響應(可用于登錄校驗失敗的場景); - 若全部返回
true
,則繼續執行后續流程。
- 若任意一個攔截器的
- HandlerAdapter 調用 Handler 業務方法
HandlerAdapter 調用 Handler(Controller 方法)的業務邏輯,處理請求(如查詢數據庫、處理參數),最終返回 ModelAndView 對象(包含業務數據 Model 和視圖名稱 ViewName,如ModelAndView("user/list", "users", userList)
)。 - 執行攔截器的后處理方法(postHandle)
Handler 執行完成后,DispatcherServlet 會倒序執行攔截器鏈中所有攔截器的postHandle()
方法(此時 ModelAndView 已生成,可在此處修改視圖或數據)。 - DispatcherServlet 調用 ViewResolver 解析視圖
DispatcherServlet 將 Handler 返回的 ModelAndView 傳遞給 ViewResolver(視圖解析器),ViewResolver 根據視圖名稱(如user/list
)和配置的視圖前綴(如/WEB-INF/views/
)、后綴(如.jsp
),解析為實際的 View 視圖對象(如/WEB-INF/views/user/list.jsp
)。 - View 渲染視圖并返回響應
View 視圖對象結合 Model 中的數據(如users
列表),渲染生成 HTML 頁面(將數據填充到 JSP 模板的標簽中),并將渲染后的響應結果返回給 DispatcherServlet。 - 執行攔截器的完成處理方法(afterCompletion)
響應返回前,DispatcherServlet 會倒序執行攔截器鏈中所有攔截器的afterCompletion()
方法(無論請求是否成功,均會執行,可用于資源釋放,如關閉流)。最終,DispatcherServlet 將響應結果返回給客戶端(瀏覽器),流程結束。
2. 工作流程流程圖(文字示意)
客戶端(瀏覽器) ↓ 1. 發送HTTP請求
Web服務器(Tomcat) ↓ 2. 轉發給DispatcherServlet(根據映射規則)
DispatcherServlet(前端控制器) ↓ 3. 調用HandlerMapping
HandlerMapping(處理器映射器) ↓ 返回:Handler + 攔截器鏈
DispatcherServlet ↓ 4. 匹配HandlerAdapter
HandlerAdapter(處理器適配器) ↓ 5. 執行攔截器preHandle()(全部true則繼續) ↓ 6. 調用Handler(Controller方法)→ 返回ModelAndView ↓ 7. 執行攔截器postHandle()(倒序)
DispatcherServlet ↓ 8. 調用ViewResolver解析視圖
ViewResolver(視圖解析器) ↓ 返回:實際View對象(如JSP) ↓ 9. View渲染(Model數據填充到View)→ 生成HTML ↓ 10. 執行攔截器afterCompletion()(倒序)
DispatcherServlet ↓ 返回響應
客戶端(瀏覽器)
關鍵總結
- DispatcherServlet 是 “中樞”:所有請求都經過它,負責協調 HandlerMapping、HandlerAdapter、ViewResolver 等組件,降低組件耦合。
- 組件職責單一:每個組件只做一件事(如 HandlerMapping 只負責找 Handler,ViewResolver 只負責解析視圖),符合 “單一職責原則”。
- 攔截器作用于流程節點:通過
preHandle
、postHandle
、afterCompletion
可在請求處理的關鍵節點插入自定義邏輯,增強靈活性。 - ModelAndView 是 “數據 + 視圖” 載體:Handler 不直接渲染視圖,而是返回 ModelAndView,由 ViewResolver 和 View 完成渲染,實現 “業務邏輯與視圖分離”。