neweastsun 2017-08-21
struts再一次包装了spring的webapplicationcontext(webapplication本源都是从servletcontext获取)
servletcontext这里有配置文件的参数等信息,还有bean之间的关联关系,并且把这种关联关系封装成map
核心结合jar包
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>
这个拦截器包装了action的context和webapplicationcontext
(一)
struts中注入webaoolicationcontext
StrutsSpringObjectFactory 实现了implements ApplicationContextAware
@Inject静态注入
从servletcontext获取webapplicationcontext
@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();
}