【1】添加Spring和Struts2需要的jar包,尤其是整合jar包struts2-spring-plugin-2.3.16.jar
不可缺少;
【2】配置applicationContext.xml
正常配置XML,其中,如果在xml中配置Action,需注意scope属性一定为prototype。
基于xml方式配置controller、service
<!-- stuts2 的action实例非单例,一定要加上域属性(默认为单例模式) -->
<bean id="personAction" class="com.struts2.actions.PersonAction" scope="prototype">
<property name="personService" ref="personService"></property>
</bean>
【3】配置web.xml
配置Struts2核心过滤器、Spring初始化容器监听器等。
<!-- ***Spring IOC 容器初始化*** -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- *********Spring的字符编码过滤器*****************-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ******Struts2核心过滤器***** -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
【4】配置struts.xml
注意此时,Action里面class属性为Sping配置文件中的bean-Id(如果使用注解,则为注解时配置的名字);
<package name="default" extends="struts-default" namespace="/">
<!-- name reference action exclude '.action' -->
<action name="person-save" class="personAction" >
<result>/success.jsp</result>
</action>
</package>
【5】实现原理
- Struts2有自己默认对象池:
<bean class="com.opensymphony.xwork2.ObjectFactory" name="struts"/>
源码:
public Object buildBean(String className, Map<String, Object> extraContext) throws Exception {
return buildBean(className, extraContext, true);
}
/**
* Build a generic Java object of the given type.
*
* @param className the type of Object to build
* @param extraContext a Map of extra context which uses the same keys as the {@link com.opensymphony.xwork2.ActionContext}
*/
public Object buildBean(String className, Map<String, Object> extraContext, boolean injectInternal) throws Exception {
Class clazz = getClassInstance(className);
Object obj = buildBean(clazz, extraContext);
/*通过反射创建bean*/
if (injectInternal) {
injectInternalBeans(obj);
}
return obj;
}
- struts-plugin.xml 中重新修改了默认对象池:
<bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />
<!-- Make the Spring object factory the automatic default -->
<constant name="struts.objectFactory" value="spring" />
SpringObjectFactory(StrutsSpringObjectFactor的父类)源码:
@Override
public Object buildBean(String beanName, Map<String, Object> extraContext, boolean injectInternal) throws Exception {
Object o;
if (appContext.containsBean(beanName)) {
o = appContext.getBean(beanName);
//首先通过IOC容器获取bean
} else {
Class beanClazz = getClassInstance(beanName);
o = buildBean(beanClazz, extraContext);
//其次,若获取不到,则通过反射构建bean
}
if (injectInternal) {
injectInternalBeans(o);
}
return o;
}