背景:百花齊放的 MVC 框架戰國時代
J2EE 陣營 MVC 框架層出不窮:老牌 Struts、WebWork;新貴 Spring MVC、Tapestry、JSF;邊緣佳作 Dinamica、VRaptor。選型直接影響專案效能、可維護性與團隊生產力。
Struts:穩重的王者
地位與歷程
- Apache Jakarta 專案,核心作者 Craig R. McClanahan
- 五年磨一劍,佔據最大市佔,文檔豐富、社群龐大、人才易招募
- 技術特性逐漸落後於新框架,但「穩定、成熟、風險低」仍是產品級首選
架構組成
- 核心控制器:
ActionServlet(單一入口)
- 業務處理:
Action、ActionForm、ActionMapping、ActionForward
- 視圖整合:JSP、Velocity、XSLT 等,內建豐富 TagLib(Bean/HTML/Logic/Nested/Template)
- 模型整合:EJB、JDBC、OJB 等,工具類支援資料庫操作
請求處理流程
ActionServlet 接收請求
- 依
struts-config.xml 映射找到 ActionMapping
- 建立/取得
ActionForm 裝載表單資料
- 委派對應
Action 執行業務邏輯
Action 返回 ActionForward 指向下一視圖
ActionServlet 轉向 JSP/Template 渲染回應
Spring MVC:輕量級全棧框架的 Web 模組
來源與哲學
- 源自 Rod Johnson 《Expert One-on-One J2EE Design and Development》實作框架(interface21)演進
- 核心主張:J2EE 實用主義——用 POJO 替代重量級 EJB,降低複雜度
- 開源、非侵入式、鬆耦合、易測試
四大核心特性
| 特性 | 內涵 | 效益 |
| 輕量 | 完整框架 < 1MB JAR;處理開銷極低;不強制繼承特定類 | 易嵌入、啟動快、無框架鎖定 |
| 控制反轉 (IoC) | 容器負責建立物件、注入依賴(而非物件自行查找 JNDI) | 鬆耦合、易單元測試、配置外部化 |
| 面向切面 (AOP) | 將事務、日誌、安全等橫切關注點從業務邏輯分離 | 業務碼純粹、橫切邏輯集中復用 |
| 容器 | 管理 Bean 生命週期、作用域、關係(單例/原型、依賴圖) | 聲明式組裝複雜應用,XML/Java Config 統一配置 |
Spring MVC 架構亮點
DispatcherServlet 統一前端控制器,支援多種處理器映射策略
- 控制器介面靈活:
Controller、AbstractController、SimpleFormController、@Controller 註解式(Spring 2.5+)
- 視圖解析器支援 JSP、Velocity、FreeMarker、PDF、Excel、XSLT 等
- 無縫整合 Spring IoC/AOP、事務、Hibernate/iBATIS、JMS 等全棧能力
關鍵差異對照表
| 維度 | Struts | Spring MVC |
| 架構侷限 | 繼承式框架,侵入性強 | POJO/註解式,非侵入 |
| 依賴管理 | 手動/Action 內查找 | IoC 容器自動注入 |
| 事務處理 | 程式化/外掛 | 聲明式 AOP 事務 |
| 測試友善度 | 需容器/模擬困難 | 單元測試極易(純 POJO) |
| 學習曲線 | 平緩,文檔豐富 | 中等,概念較多 |
| 擴展性 | 受限於繼承體系 | 高度模組化、可插拔 |
| 適用場景 | 傳統專案、團隊熟悉度高、求穩 | 新專案、敏捷開發、微服務前身、需全棧整合 |
選型建議
- 維護既有 Struts 專案 → 繼續用 Struts,漸進式引入 Spring 服務層
- 新專案、團隊接受新事物 → Spring MVC(或 Spring Boot 進一步簡化)
- 需快速原型、極簡依賴 → 考慮輕量替代品
- 核心原則:框架服務於業務,不為框架而框架