一.在spring與struts整合過程中,如何引入并初始化ApplicationContext??
有幾種方式??
1. 使用web.xml的<listener>方式引入并初始化ApplicationContext:
<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>
2. 使用web.xml的<servlet>方式引入并初始化ApplicationContext:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
3. 在struts-config.xml中以<plug-in>引入并初始化ApplicationContext:
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property
property="contextConfigLocation"
value="/WEB-INF/applicationContext.xml,/WEB-INF/action-servlet.xml" />
</plug-in>
二.struts引入spring的ApplicationContext後,如何在struts的Action中使用ApplicationContext??
1. 如果使用web.xml的<servlet>或者<listener>方式引入并初始化ApplicationContext的,
因配置檔案的位置就寫在web.xml的參數contextConfigLocation中,是以擷取了servletContext就行了,
在struts的action中擷取ApplicationContext的方法如下:
WebApplicationContext wac
= WebApplicationContextUtils.getWebApplicationContext(
request.getSession().getContext()
);
2. 但如果是在struts-config.xml中以<plug-in>引入并初始化ApplicationContext的,
其實質是spring為struts提供的一個ContextLoaderPlugIn類,此類也可以加載context的xml檔案。
因為配置檔案的位置不是寫在web.xml中,而在struts-config.xml中,引而不能直接使用上面的方法,但是也需要擷取了servletContext,
那麼,在struts的action中擷取ApplicationContext的方法如下:
WebApplicationContext context
= (WebApplicationContext)this.getServlet().getServletContext()
.getAttribute("org.springframework.web.struts.ContextLoaderPlugIn.CONTEXT.");
3.在以上三種方式下都适用的方法:
applicationContext app
=new classpathXmlApplicationContext("applicationContext.xml")
三.比較和小結:
1. 第一,二種方法的差別在于,兩種方式加載的WebApplicationContext,以不同的Key存放在ServletContext中。而如果你定義了HibernateFilter的話,spring會利用WebApplicationContextUtils來擷取WebApplicationContext,而此類并不識别ContextLoaderPlugIn類所加載的上下文,此時便會抛出異常: No WebApplicationContext found: no ContextLoaderListener registered?利用ContextLoaderListenter來加載dao、service級别的context,而對于struts的action,用ContextLoaderPlugIn加載。
2. 第三種方法的缺點很明顯, 指明配置檔案所在,耦合性增強了.
3. 有人可能會懷疑第三種情況效率是否會低,因為第三種方法以配置檔案為參數,是否意味着每次都會重新從XML檔案中加載所有的bean,但事實上不是這樣.spring的設計就是要在啟動的時候加載配置檔案,當web中再無論是用applicationContext或者是WebApplicationContext獲得beans時都不會重新加載配置檔案.
4.
雖然上述實作了在action中使用ApplicationContext,但是這樣做,和繼承spring提供的ActionSupport類沒什麼差別,因為這樣做,同樣是引入了spring的類,至少也引入了ApplicationContext類,同樣是使得Struts與Spring緊密耦合,而且action中引入ApplicationContext目的是擷取Spring管理的bean,這樣子,action類也負責了查找Spring管理的bean,這違背了控制反轉(IOC)的原則。是以一般情況下,不要在Action中引入ApplicationContext。
建議采用另一種Struts-Spring內建方式,即使用Spring的DelegatingActionProxy代理類,利用IOC将你想使用的bean以注入到Action中,而不是在Action中使用ApplicationContext擷取你想要的bean。