Struts 1.x 作為經典 MVC 框架控制層表現強勁,但缺乏依賴管理能力。Spring 提供 IoC 容器與 AOP 支持,可管理 Service、DAO 等業務組件。集成核心目標:讓 Struts Action 透過 Spring 獲取業務 Bean,而非硬編碼查找。
在 struts-config.xml 中聲明插件,載入 Spring 上下文:
<plug-in className="org.springframework.web.struts.ContextLoaderPlugin">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml"/>
</plug-in>
該插件啟動時初始化 WebApplicationContext,並綁定到 ServletContext,供後續方案使用。
Spring 提供 org.springframework.web.struts.ActionSupport,重寫 setServlet() 從插件獲取上下文,暴露 getWebApplicationContext() 與 getBean() 方法。
public class CourseAction extends ActionSupport {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
// 1. 獲取 Spring 上下文
ApplicationContext ctx = getWebApplicationContext();
// 2. 手動查找 Bean
CourseService service = (CourseService) ctx.getBean("courseService");
// 3. 業務調用
Set courses = service.getAllCourses();
request.setAttribute("courses", courses);
return mapping.findForward("jspView");
}
}
| 優點 | 缺點 |
|---|---|
| 上手快,改造成本低,邏輯直觀 | Action 依賴 Spring 具體類,控制層與容器強耦合 |
| 無需修改 struts-config.xml 的 action 配置 | 違背 IoC 原則:Action 主動「拉取」依賴,而非「注入」 |
| 兼容傳統 Struts 開發習慣 | 難以單元測試(需模擬 WebApplicationContext) |
Struts 配置中聲明的 Action 類改為 Spring 代理 DelegatingActionProxy,真正的 Action 作為 Spring Bean 定義在上下文中,依賴通過 Setter 注入。
<action path="/listCourses" type="org.springframework.web.struts.DelegatingActionProxy"/>
<bean name="/listCourses" class="com.example.web.CourseAction">
<property name="courseService" ref="courseService"/>
</bean>
關鍵約定:Bean 的 name 必須與 Struts path 完全一致,代理據此查找。
public class CourseAction extends Action { // 僅繼承 Struts 原生 Action
private CourseService courseService;
public void setCourseService(CourseService courseService) {
this.courseService = courseService; // Setter 注入
}
public ActionForward execute(...) {
Set courses = courseService.getAllCourses(); // 直接使用
request.setAttribute("courses", courses);
return mapping.findForward("jspView");
}
}
為消除 DelegatingActionProxy 的配置固化,Spring 提供專用請求處理器:
<controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor"/>
效果:struts-config.xml 中可直接聲明真實 Action 類型:
<action path="/listCourses" type="com.example.web.CourseAction"/>
運行時處理器自動從 Spring 上下文按 path 查找 Bean 並委托執行,配置更直觀,同時保持非侵入性。
Spring-Struts 集成本質是「誰控制 Action 的生命周期與依賴賦值」。方案一由 Struts 管理 Action、Spring 管理 Service,Action 主動找 Spring;方案二將 Action 納入 Spring 容器,Struts 僅持有代理引用,依賴反轉徹底。後者符合現代框架設計哲學,是生產環境推薦模式。