ContextLoaderListener(推薦)或 ContextLoaderServlet(舊版)在 web.xml 中聲明:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Listener 接收 contextInitialized 事件 → ContextLoader.initWebApplicationContext() → 創建 XmlWebApplicationContext → 存入 ServletContext 屬性 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。
WebApplicationContextUtils.getWebApplicationContext(servletContext),通用。org.springframework.web.struts.ActionSupport,直接 getWebApplicationContext() → getBean(),但每處業務邏輯需手工查找,不夠乾淨。struts-config.xml 掛載:<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation"
value="/WEB-INF/applicationContext.xml,/WEB-INF/action-servlet.xml"/>
</plug-in>
action-servlet.xml 定義 Action Bean(singleton="false" 解決線程安全),Spring 自動注入依賴:
<bean name="/userAction" class="com.web.action.UserAction" singleton="false">
<property name="businessService" ref="businessService"/>
</bean>
請求到達 → DelegatingActionProxy 代理 → 從 action-servlet.xml 實例化真實 Action → 注入服務 → 執行 execute()。
ContextLoaderPlugIn 仍將容器放入 ServletContext,Key 為 ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX + modulePrefix。自定義 TagLib、Filter、Servlet 中只需拿到 ServletContext 即可通用取容器:
WebApplicationContext ctx = (WebApplicationContext)
servletContext.getAttribute(ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX + modulePrefix);
Listener 初始化根容器,PlugIn 掛載 Struts 專用子容器並代理 Action 實例化與依賴注入,兩者共存無衝突,覆蓋 Web、Struts、非 Struts 組件所有訪問場景。