上 一篇,写了struts2中的关键问题,至于详细的集成过程,我就不细表了,除了我描述的关键问题以外,其他的都雷同。下面说说Spring的集成,网上 搜的文章中大多介绍spring和struts2的集成,都是同一套路,将spring的配置往src根目录一扔,然后在web.xml中配个监听器,然 后在struts2的配置中增加struts.objectFactory的描述。就完了,虽然好用,但是都是照葫芦画瓢,不知所以然。其实struts 既然有这个个描述,那就意味着,struts2中所有实例的获取,都要通过这个定义的ObjectFactory来获取,工厂里用什么方式获取对象就和什 么集成,所以,和spring的集成关键不在web.xml的配置上,甚至web.xml上的监听可以完全不要。下面我们就来实际的做一下:编写 XKStrutsSpringObjectFactory继承SpringObjectFactory, 代码如下:

   
   
   
   
  1. public class XKStrutsSpringObjectFactory extends SpringObjectFactory  
  2. {  
  3.     /**  
  4.      *   
  5.      */ 
  6.     private static final long serialVersionUID = 1L;  
  7.     private static final Logger LOG = LoggerFactory.getLogger(XKStrutsSpringObjectFactory.class);  
  8.  
  9.  
  10.     @SuppressWarnings("deprecation")  
  11.     @Inject 
  12.     public XKStrutsSpringObjectFactory(@Inject(value = StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_AUTOWIRE, required = false) String autoWire,  
  13.             @Inject(value = StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_AUTOWIRE_ALWAYS_RESPECT, required = false) String alwaysAutoWire,  
  14.             @Inject(value = StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_USE_CLASS_CACHE, required = false) String useClassCacheStr, @Inject ServletContext servletContext,  
  15.             @Inject(StrutsConstants.STRUTS_DEVMODE) String devMode, @Inject Container container)  
  16.     {  
  17.  
  18.         super();  
  19.         boolean useClassCache = "true".equals(useClassCacheStr);  
  20.         if (LOG.isInfoEnabled())  
  21.         {  
  22.             LOG.info("Initializing Struts-Spring integration...");  
  23.         }  
  24.  
  25.   // 关键代码
  26.         Object rootWebApplicationContext = Initialization.getInstance().getApplicationContext();  
  27.  
  28.         if (rootWebApplicationContext instanceof RuntimeException)  
  29.         {  
  30.             RuntimeException runtimeException = (RuntimeException) rootWebApplicationContext;  
  31.             LOG.fatal(runtimeException.getMessage());  
  32.             return;  
  33.         }  
  34.  
  35.         ApplicationContext appContext = (ApplicationContext) rootWebApplicationContext;  
  36.         if (appContext == null)  
  37.         {  
  38.             // uh oh! looks like the lifecycle listener wasn't installed. Let's  
  39.             // inform the user  
  40.             String message = "********** FATAL ERROR STARTING UP STRUTS-SPRING INTEGRATION **********\n" + "Looks like the Spring listener was not configured for your web app! \n" 
  41.                     + "Nothing will work until WebApplicationContextUtils returns a valid ApplicationContext.\n" + "You might need to add the following to web.xml: \n" + "    \n" 
  42.                     + "        org.springframework.web.context.ContextLoaderListener\n" + "    ";  
  43.             LOG.fatal(message);  
  44.             return;  
  45.         }  
  46.  
  47.         String watchList = container.getInstance(String.class"struts.class.reloading.watchList");  
  48.         String acceptClasses = container.getInstance(String.class"struts.class.reloading.acceptClasses");  
  49.         String reloadConfig = container.getInstance(String.class"struts.class.reloading.reloadConfig");  
  50.  
  51.         if ("true".equals(devMode) && StringUtils.isNotBlank(watchList) && appContext instanceof Cla***eloadingXMLWebApplicationContext)  
  52.         {  
  53.             // prevent class caching  
  54.             useClassCache = false;  
  55.  
  56.             Cla***eloadingXMLWebApplicationContext reloadingContext = (Cla***eloadingXMLWebApplicationContext) appContext;  
  57.             reloadingContext.setupReloading(watchList.split(","), acceptClasses, servletContext, "true".equals(reloadConfig));  
  58.             if (LOG.isInfoEnabled())  
  59.             {  
  60.                 LOG.info("Class reloading is enabled. Make sure this is not used on a production environment!", watchList);  
  61.             }  
  62.  
  63.             setClassLoader(reloadingContext.getReloadingClassLoader());  
  64.  
  65.             // we need to reload the context, so our isntance of the factory is  
  66.             // picked up  
  67.             reloadingContext.refresh();  
  68.         }  
  69.  
  70.         this.setApplicationContext(appContext);  
  71.  
  72.         int type = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; // default  
  73.         if ("name".equals(autoWire))  
  74.         {  
  75.             type = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;  
  76.         }  
  77.         else if ("type".equals(autoWire))  
  78.         {  
  79.             type = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;  
  80.         }  
  81.         else if ("auto".equals(autoWire))  
  82.         {  
  83.             type = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;  
  84.         }  
  85.         else if ("constructor".equals(autoWire))  
  86.         {  
  87.             type = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;  
  88.         }  
  89.         else if ("no".equals(autoWire))  
  90.         {  
  91.             type = AutowireCapableBeanFactory.AUTOWIRE_NO;  
  92.         }  
  93.         this.setAutowireStrategy(type);  
  94.  
  95.         this.setUseClassCache(useClassCache);  
  96.  
  97.         this.setAlwaysRespectAutowireStrategy("true".equalsIgnoreCase(alwaysAutoWire));  
  98.  
  99.         if (LOG.isInfoEnabled())  
  100.         {  
  101.             LOG.info("... initialized Struts-Spring integration successfully");  
  102.         }  
  103.     }  
  104. }  

关 键一步就在于第26行,那句代码,只要使用自己的方法获得applicationContext对象就行了。而Spring对于 ApplicationContext对象也提供了多种实现,既然咱们想自己定义配置的名称和位置,那么咱们就使用 FileSystemXmlApplicationContext,嗯,这个类的使用就不用我赘述了。很简单,实例化的时候将配置的路径传入就ok了。最 后在struts的配置中,将我们自己实现的工厂类应用上去,如:

   
   
   
   
  1. <constant name="struts.objectFactory" value="com.xk.commons.config.XKStrutsSpringObjectFactory" /> 

要 注意一点:代码71行中使用到了Cla***eloadingXMLWebApplicationContext这个类,这个类的父类中会实现 FilesystemAlterationListener接口,这个接口在struts和spring提供的jar包中是找不到的,其包含在 apache的commons的jci库中,具体到jar包为commons-jci-fam-1.0.jar 下载地址:http://commons.apache.org/jci/downloads.html

本文出自 “

My Joy is my joy ~