Struts once again wraps spring's webapplicationcontext (the source of webapplication is obtained from servletcontext)
The servletcontext contains the parameters of the configuration file and other information, as well as the association between beans, and encapsulates this association into a map
Core combined jar package
struts2-spring-plugin-2.1.6.jar
struts-plugin.xml:
<bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />
<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>
This interceptor wraps the action context and webapplicationcontext
(one)
Inject webaoolicationcontext into struts
StrutsSpringObjectFactory implements ApplicationContextAware
@Inject static injection
get webapplicationcontext from servletcontext
@Inject
public StrutsSpringObjectFactory(
@Inject(value=StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_AUTOWIRE,required=false) String autoWire,
@Inject(value=StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_AUTOWIRE_ALWAYS_RESPECT,required=false) String alwaysAutoWire,
@Inject(value=StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_USE_CLASS_CACHE,required=false) String useClassCacheStr,
@Inject ServletContext servletContext) {
super();
boolean useClassCache = "true".equals(useClassCacheStr);
LOG.info("Initializing Struts-Spring integration...");
ApplicationContext appContext = (ApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (appContext == null) {
// uh oh! looks like the lifecycle listener wasn't installed. Let's inform the user
String message = "********** FATAL ERROR STARTING UP STRUTS-SPRING INTEGRATION **********\n" +
"Looks like the Spring listener was not configured for your web app! \n" +
"Nothing will work until WebApplicationContextUtils returns a valid ApplicationContext.\n" +
"You might need to add the following to web.xml: \n" +
" <listener>\n" +
" <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>\n" +
" </listener>";
LOG.fatal(message);
return;
}
this.setApplicationContext(appContext);
int type = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; // default
if ("name".equals(autoWire)) {
type = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
} else if ("type".equals(autoWire)) {
type = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
} else if ("auto".equals(autoWire)) {
type = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
} else if ("constructor".equals(autoWire)) {
type = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
}
this.setAutowireStrategy(type);
this.setUseClassCache(useClassCache);
this.setAlwaysRespectAutowireStrategy("true".equalsIgnoreCase(alwaysAutoWire));
LOG.info("... initialized Struts-Spring integration successfully");
}
(二)
拦截器中(使用webapplicationcontext):
利用spring的context封装成struts自己的context
ActionAutowiringInterceptor (StrutsSpringObjectFactory中@Inject静态注入了webapplicationcontext)
public String intercept(ActionInvocation invocation)
throws Exception
{
if (!this.initialized)
{
ApplicationContext applicationContext = (ApplicationContext)ActionContext.getContext().getApplication().get(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (applicationContext == null)
{
if (LOG.isWarnEnabled()) {
LOG.warn("ApplicationContext could not be found. Action classes will not be autowired.", new String[0]);
}
}
else
{
setApplicationContext(applicationContext);
this.factory = new SpringObjectFactory();
this.factory.setApplicationContext(getApplicationContext());
if (this.autowireStrategy != null) {
this.factory.setAutowireStrategy(this.autowireStrategy.intValue());
}
}
this.initialized = true;
}
if (this.factory != null)
{
Object bean = invocation.getAction();
this.factory.autoWireBean(bean);
ActionContext.getContext().put("com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor.applicationContext", this.context);
}
return invocation.invoke();
}