论坛首页 Java企业应用论坛

webwork2 + spring 结合的几种方法的小结

浏览 30885 次
该帖已经被评为精华帖
作者 正文
   发表时间:2005-01-04  
webwork2 + spring 结合的几种方法的小结

参考:
http://wiki.opensymphony.com/display/WW/WebWork+2+Spring+Integration
http://forum.iteye.com/viewtopic.php?t=8509
http://forum.iteye.com/viewtopic.php?t=9939

下载:
http://xwork-optional.dev.java.net/


  昨天使用webwork和spring,使用的是SpringObjectFactory方法,突然发现validator没发生作用,折腾半天,
  换成external-ref的方法,可以了.但是觉得external-ref的方法太麻烦了.
  就是去http://xwork-optional.dev.java.net/下载了一下最新的源码,换回SpringObjectFactory的方式,发现问题解决了(重载getClassInstance解决了这个问题).
 
  于是仔细研究了一下几种组合的方法,根据前面参考中的文章,整理了一下.
 
  看了xwork-optional的源码,发现其实三种方法的源码都包含在这里了,当然也包括external-ref这种方法的源码,只是换了包名和文件名,但是源码基本没变.你可以仔细看看.
 
  1.External-Ref
 
  这种方法看起来比较烦琐,可能现在都改用第3种方法了.
 
  第一步:在web.xml里面增加一个listener,如下
 
		<listener>
			<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
		</listener>
		
		<listener>
			<listener-class>com.opensymphony.xwork.spring.SpringExternalReferenceResolverSetupListener</listener-class>
		</listener>


第二步:在Spring里面配置类似Dao之类的bean,例如

		<bean id="myDAO" class="com.ryandaigle.persistence.MyDAO" singleton="true" />


第三步:配置XWork.xml,例如

		<package name="default" extends="webwork-default"
			externalReferenceResolver="com.opensymphony.xwork.spring.SpringExternalReferenceResolver">		
			<interceptors>
				<interceptor name="reference-resolver" class="com.opensymphony.xwork.interceptor.ExternalReferencesInterceptor"/>
				<interceptor-stack name="myDefaultWebStack">
					<interceptor-ref name="defaultStack"/>
					<interceptor-ref name="reference-resolver"/>
				</interceptor-stack>
			</interceptors>
			
			<default-interceptor-ref name="myDefaultWebStack"/>
			
			<action name="myAction" class="com.ryandaigle.web.actions.MyAction">
				<external-ref name="DAO">myDAO</external-ref>
				<result name="success" type="dispatcher">
					<param name="location">/success.jsp</param>
				</result>
			</action>
		
		</package>
	

 
 
 
 
  2.SpringObjectFactory
  我一直用这种方法,因为以前觉得是xwork本身提供的方法,升级有保障.
 
  配置方法:
  第一步.在spring的 applicationContext.xml (根据实际情况决定) 里面定义你的action,例如
 
		<bean name="some-action" class="fully.qualified.class.name" singleton="false">
		    <property name="someProperty"><ref bean="someOtherBean"/></property>
		</bean>
		


可以看到,可以使用Spring的特性来给你的action设置属性等,当然也可以使用Spring的拦截器等 (可以使用不一定等于推荐使用)

注意一定是singleton="false",因为xwork的action是这样要求的.

  第二步.在xwork.xml里定义你的action定义
 
		<action name="myAction" class="some-action">
		    <result name="success">view.jsp</result>
		</action>  

 
  第三步.要使上面的关联生效,还要用我们的SpringObjectFactory来替换Xwork的默认ObjectFactory.
    最新的SpringObjectFactory里面,有两种方法,其中我觉得A方法更直观一些.
   
    A:修改web.xml
   
  	  		<!-- 这个是spring的listener,可以改为你的自定义的spring的Listenter -->
			<listener>
				<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
			</listener>
			
		
			<!-- 这个必须在 Spring ContextLoaderListener 的后面 -->
			<listener>
			  <listener-class>com.opensymphony.xwork.spring.SpringObjectFactoryListener</listener-class>
			</listener>

   
    B.在spring的applicationContext.xml (根据实际情况决定)里面定义一个bean,例如
   
  	  	<bean id="spring-object-factory" class="com.opensymphony.xwork.spring.SpringObjectFactory" 
  	  		init-method="initObjectFactory"/>

   
    这样Spring会自动调用initObjectFactory方法来替换Xwork的默认ObjectFactory
   
   
 
  3.ActionAutowiringInterceptor
    这个方法是最近出现的,可能是最简洁的方法,但是不知道性能上有没有问题,我觉得jdk1.4以后应该没有任何问题吧,至于实际效果你的自己测试一下.
   
    第一步:配置web.xml
  	  		<!-- 这个是spring的listener,可以改为你的自定义的spring的Listenter -->
			<listener>
				<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
			</listener>
	

第二步配置xwork.xml里面的拦截器

		<interceptors>
		  <interceptor name="autowire" class="com.opensymphony.xwork.spring.interceptor.ActionAutowiringInterceptor">
		    <param name="autowireStrategy">@org.springframework.beans.factory.config.AutowireCapableBeanFactory@AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE</param>
		  </interceptor>
		  <interceptor-stack name="autowireDefault">
		    <interceptor-ref="autowire" />
		    <interceptor-ref="defaultStack" />
		  </interceptor-stack>
		</interceptors>
   
    你的拦截器里都要包含autowire,例如这个autowireDefault就相当于以前的默认的拦截器了.
    其中的拦截器策略可以配置,上面配置的是根据类型,如果不配置,默认是根据名字.
   
    一共有四种策略:
    AUTOWIRE_CONSTRUCTOR
    AUTOWIRE_BY_TYPE
    AUTOWIRE_BY_NAME
    AUTOWIRE_AUTODETECT
   
   
    这种方法执行原理就是查找你的action的所有字段,如果和Spring的定义bean有相同的,就自动设置.
   
    假设你的Spring的applicationContext.xml里面有这样一个定义:
   
    	<bean id="userManager" class="com.test.UserManager" />

   
  如果你在xwork.xml  里面定义的某个action有一个字段叫userManager,那么在运行时刻就会自动被设置为Spring的配置文件里定义的Bean.

以上如有不对指出,还请指出
   发表时间:2005-01-04  
发表文章的时候记得构上:
在这篇文章里禁止HTML标签

要不然一些代码好像显示有问题。
0 请登录后投票
   发表时间:2005-01-04  
不错,很详细拉!
0 请登录后投票
   发表时间:2005-01-04  
http://forum.iteye.com/viewtopic.php?p=49849#49849

这应该是第四种方法了。
0 请登录后投票
   发表时间:2005-01-04  
robbin 写道
http://forum.iteye.com/viewtopic.php?p=49849#49849

这应该是第四种方法了。


No, No 就是上面的第3种ActionAutowiringInterceptor

Robbin不认真读帖子,hoho
0 请登录后投票
   发表时间:2005-01-07  
打了一个包,包含jar和src (不包含lib)

我用jdk1.4编译的

不过还是建议去拿最新的,我上次就是用旧的,结果遇到旧版本中的bug.
0 请登录后投票
   发表时间:2005-01-07  
spring嘟嘟 写道
<interceptor-ref name="autowire"/>
<interceptor-ref name="defaultStack"/> 


这么写吧


en en 
0 请登录后投票
   发表时间:2005-01-12  
第三种方法有什么缺陷吗?
0 请登录后投票
   发表时间:2005-01-12  
tel9693 写道
第三种方法有什么缺陷吗?

因为我下载的包不对,所以就第三种方式的问题请教过一位网友,那位网友说第三种方法不好,让我看它的源代码,不过我从源代码并没有看出什么来。
其实,它无非是用了spring的自动的组件装配方式而矣。

再细想,确实想清楚了这种自动装配方式的缺陷:
使用这种方式的主要问题是,它会为action的每一个属性去找有没有定义在spring的bean配置文件中的名字相同的bean,如果找到了就会自动地为这个action组装。

这样带来的问题就是,如果你的action的某个属性是不想被自动装配的,而另外一个action的同名同类型的属性是需要自动装配的,你就不好处理了。

action的属性起名时需要小心这种情况。

另外,我没有深入研究过第一、二种方式,不知道这第三种方式在效率上与前两种方式有什么差别,不过第三种方式的效率肯定是不会太好的。
0 请登录后投票
   发表时间:2005-01-12  
如果为了效率,不如你不要用IoC了,那都是reflection,效率低得很呐。

既然你都要自动装配了,你干吗非要给不需要自动装配的属性声明相同的名称呢?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics