Spring MVC 雖非 Spring 核心,但其設計極具洞見:以 IOC 容器驅動所有組件裝配、明確 ModelAndView 強化 Model 概念、單例 Controller 配合無狀態設計、暴露 Servlet API 而非過度封裝、提供實用攔截器鏈與靈活視圖解析器。本文從八大設計決策切入,對比 Struts/WebWork 2,揭示其優雅與實用並重的架構哲學。
| # | 決策 | Spring MVC | Struts / WebWork 2 | 優勢 |
|---|---|---|---|---|
| 1 | 配置機制 | 純 IOC Bean 定義(applicationContext.xml) | 專屬 XML(struts-config.xml / xwork.xml) | 享有完整 IOC 能力:AOP、FactoryBean、屬性編輯器、SpEL、條件裝配 |
| 2 | Model 抽象 | ModelAndView 封裝 Model Map + View 名稱 | Struts: 隱式放入 Request/Session; WebWork: Action 即 Model | 職責清晰、支援多種 View 技術(JSP/Velocity/FreeMarker/PDF/Excel/JSON/RDF) |
| 3 | Controller 實例策略 | Singleton(預設),無狀態 | Struts: Singleton; WebWork: 每請求新實例 | 減少物件創建/GC,現代 JVM 多執行緒效能極佳,無狀態設計避免併發問題 |
| 4 | Servlet API 暴露 | Controller 簽名可直接接收 HttpServletRequest/Response | WebWork: 僅提供 Getter/Setter/ActionContext | 需要時可直接操作 Response 輸出二進位流、設定 Header、處理複雜 Cookie |
| 5 | 攔截器機制 | HandlerInterceptor:preHandle/postHandle/afterCompletion | WebWork: 強大 Interceptor Stack(Pragmatic AOP) | 足夠 90% 場景;缺 Around 型,需用 ThreadLocal 傳遞狀態(如計算耗時) |
| 6 | 多動作控制器 | MultiActionController 反射分派 | Struts: DispatchAction; WebWork: 缺乏同等機制 | 相關功能聚合單一類,減少類爆炸 |
| 7 | 視圖解析策略 | 豐富 ViewResolver:InternalResource/Velocity/FreeMarker/Xslt/Json/BeanName/UrlBased | Struts/WebWork: 需在配置映射 logical name → physical path | 支援約定優於配置(如 BeanNameViewResolver 直接對應 Bean 名稱) |
| 8 | 標籤庫設計 | spring:bind 包裝原生 HTML,保留原生標籤外觀 | Struts/WebWork: 強制使用自定義標籤 | 美工可直接編輯 HTML,無需學習標籤語法 |
DispatcherServlet.init() → 建立 WebApplicationContext → 掃描所有 Bean。HandlerMapping(預設 BeanNameUrlHandlerMapping + DefaultAnnotationHandlerMapping)匹配 Controller。HandlerAdapter 調用 Controller → 回傳 ModelAndView。preHandle → Controller → postHandle → View 渲染 → afterCompletion。ViewResolver 解析 View → View.render(model, request, response)。public class RegexUrlHandlerMapping extends AbstractUrlHandlerMapping {
@Override protected Object getHandlerInternal(HttpServletRequest req) {
String path = getPathWithinApplication(req);
for (Map.Entry e : urlMap.entrySet()) {
if (e.getKey().matcher(path).matches()) return e.getValue();
}
return null;
}
}
PROPAGATION_REQUIRED
作為子專案,提供「頁面流」配置:flow.xml 定義狀態、轉移、決策點、子流程,解決精靈式表單、複雜業務流程的導航與狀態管理,現已整合進 Spring Framework 核心。
Spring MVC 以「最小驚訝原則」設計:沒有強迫你學習新配置語言(用 IOC)、沒有隱藏 Servlet API(需要時可用)、沒有過度設計攔截器(夠用即可)、沒有綁定特定視圖技術(隨時換)。這種克制與開放的平衡,正是其歷經十餘年仍活躍於生產環境的關鍵。