Spring 2.0集成Tapestry 5.0

http://www.itren.cn 时间:2007-12-24 14:06:32 来源:IT168 作者:陈雄华
 
  【IT168 技术文档】概述

  Tapestry是一个基于组件的Web框架,以至于用它开发Web应用和开发传统的GUI应用很类似。使用Tapestry开发Web应用时,你无须关注以操作为中心Servlet API,引用Tapestry网站上的一句话:“Tapestry用对象、方法、属性替代以往的URL和查询参数,重新诠释Web应用开发”。

  当前Tapestry的最新版本是5.0,新版本添加了很多新的功能,其中最让人感慨的是,Tapestry原有的IoC功能,现在已经越来越弱化,Tapestry将在不久将来完全放弃自身的IoC实现,转而使用Spring IoC。和Struts 2一样,Tapestry 5.0也专门提供了一个集成将Tapestry集成到Spring中的插件——对于Spring来说,越来越有“朵朵向阳开,高歌欢庆新春来”的气息了。

  Tapestry为集成Spring提供的类

  Tapestry 5.0提供了一个用于集成Spring中的tapestry-spring-5.0.x.jar类包,该类包中有三个重要的类,下面我们分别对此进行简单的说明。

  ·SpringObjectProvider:ObjectProvider的实现类,它从Spring容器中获取Bean;
  ·SpringBean:这是一个注解类,你可以在Tapestry类的属性变量或方法入参中标注该注解,这样Tapestry就会自动根据SpringObjectProvider从Spring容器中获取对应的Bean并完成动态注入;
  ·SpringModule:Tapestry使用该类保存Spring容器的引用,确切地说它包含了WebApplicationContext实例的引用。

  SpringObjectProvider

  我们知道Tapestry拥有一套自己的IoC实现,其中org.apache.tapestry.ioc.ObjectProvider是Tapestry IoC的重要接口,它相当于Spring的BeanFactory,负责创建并返回Bean的实例。SpringObjectProvider实现了ObjectProvider接口,它不去亲自创建Bean实例,相反它通过访问Spring容器获得Bean实例。
         
         
代码清单 4 SpringObjectProvider package org.apache.tapestry.spring; … public class SpringObjectProvider implements ObjectProvider { … public SpringObjectProvider(Log log, @InjectService( " WebApplicationContext " ) WebApplicationContext context) ①通过Tapestry的基础设施注入Spring容器引用 { _log = log; _context = context; } private synchronized void loadBeanNames() { … } public < T > T provide(Class < T > objectType, AnnotationProvider annotationProvider, ObjectLocator locator) ② 从Spring容器中获取Bean { SpringBean annotation = annotationProvider.getAnnotation(SpringBean. class ); if (annotation == null ) return null ; String beanName = annotation.value(); Object raw = _context.getBean(beanName, objectType); return objectType.cast(raw); } }

  该类在实例化时,Tapestry框架会将Spring容器的WebApplicationContext引入传递进来,通过
  ①处的构造函数你可以清楚地看到这点。
  ②处的方法是ObjectProvider接口的方法,这个方法看起来挺奇怪,这是因为Tapestry 5.0已经不采用基于XML的配置机制,相反它采用JDK 5.0注解的机制直接在类中通过注解进行装配。如果Tapestry组件类的属性或方法入参需要使用Spring容器的Bean进行注入,只需要标注上@SpringBean就可以了,Tapestry框架通过扫描组件类,为所有标注了@SpringBean的属性或入参注入Spring中的Bean。由于@SpringBean包含了Bean的名字,而被标注的属性或入参提供了对象的类型,这样SpringObjectProvider就可以按“名字+类型”获取Spring中相应的Bean了。

  SpringBean

  SpringBean是一个标准的JDK 5.0注解类,用于标注Tapestry组件类的成员变量和方法入参,为Tapestry框架提供元数据信息,以便使用Spring容器中的Bean对标注对象进行依赖注入。

         
         
package org.apache.tapestry.spring; … @Target({ FIELD, PARAMETER }) ①可以用于标注成员变量和方法入参 @Documented @Retention(RUNTIME) public @interface SpringBean { String value(); ②可以通过值指定需要注入的Bean名称 }

  SpringModule

  SpringModule从ServletContext中获取WebApplicationContext,并将SpringObjectProvider注册为ObjectProvider的实现类,SpringModule将作为Tapestry的一个基础设施。

         
         
package org.apache.tapestry.spring; import org.apache.tapestry.ioc.ObjectProvider; import org.apache.tapestry.ioc.OrderedConfiguration; import org.apache.tapestry.ioc.ServiceBinder; import org.apache.tapestry.ioc.annotations.InjectService; import org.apache.tapestry.services.Context; public class SpringModule { public static void bind(ServiceBinder binder) { ①将SpringObjectProvider作为ObjectProvider的实现类 binder.bind(ObjectProvider. class , SpringObjectProvider. class ) .withId( " SpringObjectProvider " ); } ②注入Tapestry的Context(是Tapestry为ServletContext提供的别名类) public static WebApplicationContext build(@InjectService( " Context " ) Context context) { WebApplicationContext springContext = (WebApplicationContext) context .getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_A return springContext; } … }

  Tapestry将这些类打包在tapestry-spring-5.0.x.jar中,该JAR包中有一个MANIFEST.MF标明文件,文件中通过以下语句指定了Tapestry的模块类:

         
         
Tapestry - Module - Classes: org.apache.tapestry.spring.SpringModule

  这样,在Tapestry启动时,SpringModule类自动被初始化,并注入Tapestry的Context实例(其实就是ServletContext),这样SpringModule实例就包含Spring容器的引用了。

  在了解了Tapestry为集成Spring做了哪些准备后,下面我们将开始讨论如何通过具体配置集成Spring,让Tapestry的组件类通过注解引用Spring的Bean。

  Tapestry集成Spring的具体配置步骤

  下面是Spring的配置文件,它定义了多个Bean,我们希望Tapestry能够直接引入bbtForum Bean:

         
         
<? xml version = " 1.0 " encoding = " UTF-8 " ?> < beans xmlns = " http://www.springframework.org/schema/beans " xmlns:xsi = " http://www.w3.org/2001/XMLSchema-instance " xsi:schemaLocation = " http://www.springframework.org/schema/beans http: // www.springframework.org/schema/beans/spring-beans-2.0.xsd"> < bean id = " bbtForum " class = " com.baobaotao.service.BbtForum " /> </ beans >

  Tapestry的组件类直接通过注解引用Spring容器中的Bean,来看一下UserRegister如何引用bbtForum Bean:

         
         
package com.baobaotao.pages; import org.apache.tapestry.annotations.Inject; import org.apache.tapestry.spring.SpringBean; public class UserRegister { @Inject @SpringBean( " bbtForum " ) ①通过注解,Tapestry将在启动时注入Spring容器中的Bean private BbtForum _bbtForum; void onSuccess() { … } }

  在编写好通过注解引用Spring容器的Bean的组件类后,剩下的工作就是如何正确配置web.xml以便组件类能够真正注入Spring Bean并正确地工作起来:

         
         
代码清单 5 web.xml < web - app > < context - param > ① Tapestry通过该上下文参数确定应用程序类所在的包 < param - name > tapestry.app - package </ param - name > < param - value > com.baobaotao </ param - value > </ context - param > < context - param > ② Spring配置文件 < param - name > contextConfigLocation </ param - name > < param - value > classpath:baobaotao -* .xml </ param - value > </ context - param > < filter > ③ Tapestry过滤器,既负责初始化Tapestry,又负责截获框架处理的URL请求 < filter - name > app </ filter - name > < filter - class > org.apache.tapestry.TapestryFilter </ filter - class > </ filter > < filter - mapping > < filter - name > app </ filter - name > < url - pattern > /* </url-pattern> </filter-mapping> <listener> ④ 初始化Spring容器 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>

  TapestryFilter扮演着重要的角色,它一方面负责初始化Tapestry框架,在初始化时就着手将Spring容器中的Bean注入到标注@SpringBean注解的组件类中;另一方面它还负责截获URL请求,以便交由Tapestry框架进行具体的处理。

  当然,我们也需要在web.xml中配置好Spring相关的配置启动Spring容器,这样Tapestry才能正确引用到Spring容器中的Bean。

  小结

  简而言之,要将Tapestry 5和Spring 2.0进行集成,你仅需要进行以下两个小小的步骤就可以了:
  1) 将tapestry-spring-5.0.x.jar添加到类路径中;

  2) 在组件类需要注入Spring容器Bean的地方使用@SpringBean注解。
  集成成功后,在Tapestry 5组件类中需要注入Spring容器中Bean的地方(可以是成员变量或方法入参)直接使用@SpringBean注解进行标注就可以了。


 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值