转自:http://lisaiqiang1101.blog.163.com/blog/static/17398426820111611450735/
Struts2与Spring进行整合的根本目的就是要让 Spring为Struts2的Action注入所需的资源对象,它们整合的原理则是只要导入了struts2的spring插件包,不需要进行任何额外的配置,Struts2的Action实例对象将由struts2的spring插件创建,该插件会按照Action的属性名称自动从spring容器中查找相同名称的bean对象对Action进行装配, 显然,Struts2的spring插件需要获得spring容器对象,这个spring容器对象是谁创建出来?Struts2的Spring插件又是如何获得Spring容器的呢?在web开发方面,Spring除了提供自己的spring mvc这个web框架之外,它也为web开发提供了最基本的支持,以便在不使用spring mvc的web环境下使用spring,这就是通过 org.springframework.web.context.ContextLoaderListener创建出 WebApplicationContext容器对象, 并将创建出来的WebApplicationContext对象存储进了Web应用程序的application作用域中,存储时的key为 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE这个常量表示的字符串,以后在Web应用程序中就可以使用 application.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) 语句, 或Spring提供的工具方法 WebApplicationContextUtils.getWebApplicationContext(application)来获得 spring容器对象。ContextLoaderListener使用contextConfigLocation这个ServletContext初始化参数来指定WebApplicationContext容器对象的配置文件,如果没有配置contextConfigLocation这个 ServletContext的初始化参数,ContextLoaderListener则默认使用/WEB-INF /applicationContext.xml作为配置文件。 为了简便,我们这里采用默认的配置文件,所以,不需要配置contextConfigLocation这个ServletContext的初始化参数,只需要保证spring配置文件的路径和名称为/WEB-INF/applicationContext.xml即可。为了以后能轻松编写出spring整合hibernate的配置文件,最好的办法还是在已有的配置文件基础上进行修改,所以,我们就直接将petclinic的WEB-INF目录下的 applicationContext-hibernate.xml文件拷贝进自己的web项目中, 并改名为applicationContext.xml,然后参照petclinic的web.xml的内容修改自己的web项目中的web.xml文件,即将petclinic的web.xml文件中的如下一段内容复制到自己的web.xml文件中:
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
Struts2与Spring的集成要用到Spring插件包,这个包是同Struts2一起发布的。Spring插件是通过覆盖(override)Struts2的ObjectFactory来增强核心框架对象的创建。当创建一个对象的时候,它会用Struts2配置文件中的class属性去和Spring配置文件中的id属性进行关联,如果能找到则由Spring创建,否则由Struts2框架自身创建,然后由Spring来装配。Spring插件具体有如下几个作用:
1. 允许spring来创建Action、Interceptror和Result
2. 由Struts创建的对象能够被Spring装配
3. 提供了2个拦截器来自动装配action,如果没有使用Spring ObjectFactory的话
这里要注意的是,我们不必在Spring中去注册action,尽管我们可以这么去做,通常Struts框架会自动的从action mapping中创建action对象。
要实现与Struts与Spring的集成有如下几步
1.将struts2-spring-plugin-2.0.8.jar文件包含到我们的应用中,放到WEB-INF/lib目录下面即可。在这个插件包中有个struts-plugin.xml文件,它的内容如下:
<struts> <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" /> <constant name="struts.objectFactory" value="spring" /> <package name="spring-default"> <interceptors> <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/> <interceptor name="sessionAutowiring" class="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor"/> </interceptors> </package> </struts>
这里它将框架常量struts.objectFactory覆盖了,设置为”spring”,其实这里是使用了缩写,我们可以写全称:org.apache.struts2.spring.StrutsSpringObjectFactory。这个缩写的”spring”是和bean配置中的name属性相对应的。默认情况下所有由框架创建的对象都是由ObjectFactory实例化的,ObjectFactory提供了与其它IoC容器如Spring、Pico等集成的方法。覆盖这个ObjectFactory的类必须继承ObjectFactory类或者它的任何子类,并且要带有一个不带参数的构造方法。在这里我们用org.apache.struts2.spring.StrutsSpringObjectFactory代替了默认的ObjectFactory。
此外,上面我们说了,如果action不是使用Spring ObjectFactory创建的话,插件提供了两个拦截器来自动装配action,默认情况下框架使用的自动装配策略是name,也就是说框架会去Spring中寻找与action属性名字相同的bean,可选的装配策略还有:type、auto、constructor,我们可以通过常量struts.objectFactory.spring.autoWire来进行设置。