Struts2 默認將 Action 配置為單例,但在 Web 開發中強烈建議改為多例,以避免併發請求下的屬性污染問題。
param1=valueA,Action 實例的 param1 被設置為 valueA。param1 保持上次值 valueA(不會自動重置為 null)。param1=valueA,導致數據錯亂、權限繞過等嚴重 Bug。根因:單例模式下,Action 實例屬於類級別,生命周期贏應用上下文。多線程併發訪問同一實例的屬性,無線程隔離。
| 模式 | 配置示例 | 適用場景 |
|---|---|---|
| 單例 | <bean id="userAction" class="com.xxx.UserAction" scope="singleton"> | 無狀態服務、工具類、常量持有者 |
| 多例 | <bean id="userAction" class="com.xxx.UserAction" scope="prototype"> | 所有接收請求參數的 Action |
在 struts.xml 中直接聲明:
<action name="userAction" class="com.xxx.UserAction" method="execute">
<!-- 強制多例,Struts2 會忽略 Spring 的 scope 設置 -->
<param name="className">com.xxx.UserAction</param>
</action>
或在 Spring 配置中顯式指定 scope="prototype",並確保 Struts2 使用 Spring 創建 Bean(需配置 struts.objectFactory = spring)。
Struts2 Action 單例是歷史遺留默認值,實戰中必須顯式改為多例。這不是優化選項,而是正確性前提。配置成本極低,收益極大——消滅一大類難以復現的併發 Bug。