【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;
}