实验Webwork2.2与Spring的Auto-wire(1)

前几天看到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、英文参考是WebworkConflunce上的文章(不好意思,基本上是翻译这篇文章):

Enabling Spring Integration

http://wiki.opensymphony.com/display/WW/Spring

3Other 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中的beanname与你程序中的actionname属性进行匹配。系统默认使用这种方式(如果不写上面那句的话)。

type

通过在Spring中注册的bean中寻找与你程序中的actionname相同的属性来匹配。这需要保证Spring中一个类只能注册一次(即不允许部同名但同类的Spring配置)

auto

Spring试图自动检查最好的Auto-wire方式。

constructor

Spring会根据constructor的参数来匹配action。(webwork这里没有作更多说明,根据Spring的规则,这种方式应该与type类似,只不过这里不是匹配setter,而是匹配constuctor的参数。)

其实,看看Spring的相关书籍,其实这就是Spring的四种Auto-wire方式,分别对应:byNamebyTypeautodetectconstructor。可以参考Pro Spring的第4章的内容“Auto-Wireing Your Beans”。

然后说明了一下方式,配置了auto-wire以后每次都回试图通过Spring来匹配对象实例。如果Spring没有创建这个Bean,那么Webwork会自己创建它。同时,要在web.xml中注册SpringLisener来打开这个功能:

<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 ScopeSpring

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(就是指byNameAuto-wring),或者byTypeAutowire(这种情况下一个类型只能在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>

这里,你的SpringapplicationContext.xml中有一个名为“bar”的bean。注意com.acme.Foo这个action不需要修改属性,它会自动autowire的。

记住:这不是必须的。这只在这种情况才必须,你希望覆盖掉已经在Webwork中创建的action,并且需要通过Spring支持但不能自动实决定的拦截器和IoC来装饰它的时候。记住,WebworkSpring继承只是标准的IoC,使用你指定的任何auto-wiring,甚至即使你没有显示的在Spring中映射action。所以一般来说你不需要这样做,但是如果需要的时候你最好知道这是如何实现的。

这段说的不太清楚,可能我翻译的不好。但是我理解它的意思是,可以不用修改class的名字,因为不修改它也会自动应用SpringAOP和其它IoC功能,当然是根据auto-wire的匹配。但是如果需要特别的确定要从Spring中装饰后再使用这个action,那么可以把class的属性修改掉。

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.