前几天看到BJUG的朋友说最近大家都不写技术Blog了,我实在是没看什么东西,今天正好要搞Webwork2+Spring,体验了一下新版本的集成,做了点翻译,还顺道作了点小实验。
基于Spring 1.2.5 + Webwork 2.2 Beta3
1、中文参考是飞云小侠的——《WebWork2.2中结合Spring:"新的方式"》:
http://www.jscud.com/srun/news/viewhtml/4_2005_9/134.htm
2、英文参考是Webwork的Conflunce上的文章(不好意思,基本上是翻译这篇文章):
Enabling Spring Integration:
http://wiki.opensymphony.com/display/WW/Spring
3、Other Spring Integration:
http://wiki.opensymphony.com/display/WW/Other+Spring+Integration
其中:
在webwork.properties中通过这条设置打开SpringObjectFactory:
webwork.objectFactory = spring
而修改autoWire的工作方式则通过这个设置:
webwork.objectFactory.spring.autoWire = type
autoWire其实就是webwork寻找Spring已经创建的bean的方式,有如下四种方式可以设置:
name |
通过对Spring中的bean的name与你程序中的action的name属性进行匹配。系统默认使用这种方式(如果不写上面那句的话)。 |
type |
通过在Spring中注册的bean中寻找与你程序中的action的name相同的属性来匹配。这需要保证Spring中一个类只能注册一次(即不允许部同名但同类的Spring配置) |
auto |
Spring试图自动检查最好的Auto-wire方式。 |
constructor |
Spring会根据constructor的参数来匹配action。(webwork这里没有作更多说明,根据Spring的规则,这种方式应该与type类似,只不过这里不是匹配setter,而是匹配constuctor的参数。) |
其实,看看Spring的相关书籍,其实这就是Spring的四种Auto-wire方式,分别对应:byName、byType、autodetect、constructor。可以参考Pro Spring的第4章的内容“Auto-Wireing Your Beans”。
然后说明了一下方式,配置了auto-wire以后每次都回试图通过Spring来匹配对象实例。如果Spring没有创建这个Bean,那么Webwork会自己创建它。同时,要在web.xml中注册Spring的Lisener来打开这个功能:
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
这里Webwork提出了一个提示:需要更多的ApplicationContext配置文件么?
如果使用了Spring的标准Listener来结合,那么可以除了aaplicationContext.xml还配置多个xml配置文件。可以通过下面的配置来实现,需要加到web.xml里面。
<!– Context Configuration locations for Spring XML files –>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext-*.xml
/WEB-INF/spring-daos.xml
/WEB-INF/spring-actions.xml
</param-value>
</context-param>
这个可以参考Spring文档。
Spring中的配置样例
这里,你可以添加标准的Spring配置文件,在WEB-INF/applicationContext.xml。下面是一个例子:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="autodetect">
<bean id="personManager" class="com.acme.PersonManager"/>
…
</beans>
从使用内建IoC转移到使用Spring
转移很容易。Spring的配置就如上所述。完成融合,你需要:
1、 将你的components的配置从components.xml适当转移到applicationContext.xml。然后就可以安全的删除components.xml了。
2、 从xwork.xml的拦截器栈(interceptor stack)中移除Component Interceptor。虽然不移除也无伤大雅,但是留下它已经是个冗余了。
Session Scope和Spring
Spring目前不支持session scoped components。不过计划在Spring 1.3 release中整合该功能。现在,你必须使用Spring Session Componnets Workarounds。
从Spring中初始化Actions
一般,xwork.xml指明了每个Actions的具体类。当使用SpringObjectFacotry(如上面配置的过程),意味着将通过Spring来创建action,然后来组装(wire)他们之间的依赖,根据设定的auto-wire行为。SpringObjectFactory将会应用所有的预处理工作,例如代理你的action的事物(transactions)、安全(security)、等等。这样不需要明确配置,Spring会自动装配它们。大部分应用中,这就是你所要做的全部工作,使你的actions的服务和依赖关系被执行。
我们强烈建议使用声明的方式来让Spring知道你的actions之间的依赖。这包括自动的装配具有相同的name的属性和bean(就是指byName的Auto-wring),或者byType的Autowire(这种情况下一个类型只能在Spring中注册一次)。或者还可以使用JDK5种的annotations来声明事物或者安全的配置,而不是通过applicationContext.xml,这样你就不需要在所有配置文件来维护它们了。
然而,有时你想让bean通过Spring自动管理。这很有用,例如,如果你想配置复杂的AOP或者Spring支持的技术到beans上,例如Acegi。这样,你需要将所有的配置写到applicationContext.xml里面,然后改变WebWork action中的class属性,使之与Spring中的bean name定义相同,代替原来使用的真实类名。
你的xwork.xml文件中的class属性会改变,就像下面这样:
<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.1.dtd">
<xwork>
<include file="webwork-default.xml"/>
<package name="default" extends="webwork-default">
<action name="foo" class="com.acme.Foo">
<result>foo.ftl</result>
</action>
</package>
<package name="secure" namespace="/secure" extends="default">
<action name="bar" class="bar">
<result>bar.ftl</result>
</action>
</package>
</xwork>
这里,你的Spring的applicationContext.xml中有一个名为“bar”的bean。注意com.acme.Foo这个action不需要修改属性,它会自动autowire的。
记住:这不是必须的。这只在这种情况才必须,你希望覆盖掉已经在Webwork中创建的action,并且需要通过Spring支持但不能自动实决定的拦截器和IoC来装饰它的时候。记住,Webwork的Spring继承只是标准的IoC,使用你指定的任何auto-wiring,甚至即使你没有显示的在Spring中映射action。所以一般来说你不需要这样做,但是如果需要的时候你最好知道这是如何实现的。
这段说的不太清楚,可能我翻译的不好。但是我理解它的意思是,可以不用修改class的名字,因为不修改它也会自动应用Spring的AOP和其它IoC功能,当然是根据auto-wire的匹配。但是如果需要特别的确定要从Spring中装饰后再使用这个action,那么可以把class的属性修改掉。