本人翻译目的是用来学习Tapestry5的,共享出来希望大家批评指正。计划持续翻译。
chinajavawolf
Tapestry IoC 装饰器
装饰是一个非常流行的设计模式的名字。使用装饰,一个现有对象的行为可以被扩展而不需要改变对象的实现。
代替的是,一个新的对象被放置在现有对象的周围。所有其他的都能看到这个新对象,术语称为拦截器。这个拦截器实现了与被装饰的根基(underlying)对象同样的接口。
一个共通的例子是Java I/O库。抽象的InputStream基类有一个非常简单的API用来从流中读字节(和一些其他内容)。InputStream的子类提供了广泛的选择,比如缓存,加密或解密,连同对通过流读到的数据来源的控制。所有这些涉及到的都被装入到不同的InputStream实现中了,并且所有可以被连接一起在在一种管道内的,使用共同的InputStream API。
Tapestry IoC使用一个类似的方法,一个或更多个拦截器对象,所有都实现服务接口,串接在一起。这个服务的代理(负责即时深产服务实现的实例)是在管道的末端,核心服务实现在另一个上。
对于服务接口中的每一个方法,拦截器对象可以执行某些操作在核心服务实现上的同一方法重新调用之前或之后。这是另一个设计模式:委托模式(delegation)。一个拦截器可以捕获根基(underlying)实现抛出的异常然后对他们作出反应。一个非常聪明的拦截器可以在抛出异常时重新尝试一个方法,或者可以“缓和”一个检查的异常通过包裹它在一个运行时异常内。
装饰器经常被用在横切关系的上下文内,比如l日志或事务管理。这个方法是一种切面导向设计。
这一种横切关系是延迟初始化的服务。在HiveMind中,服务仅在需要时被创建,当一个服务接口的方法被第一次调用时。这个关系通过Tapestry IoC框架自身被支持,但类似的关系容易实现为装饰器。
鉴于流行的AspectJ框架改变你类的编译字节码(称为过程“织入”),通过Tapestry IoC,这个方法包裹你现有的代码在新对象中。这些包裹的对象经常在运行时被动态的创建。
在一个单独得服务上有多个装饰器也是很普通的。在这种情况下,拦截器对象的整个堆栈将被创建,每个都委派给下一个。Tapestry IoC提供装饰器发生的控制顺序。
装饰通过服务装饰方法被控制。通常,一个可再用的服务存在的日常工作是创建和实例化一个新对象。
服务装饰方法
- package org.example.myapp.services;
-
- import org.apache.tapestry.ioc.services.LoggingDecorator;
-
- public class MyAppModule
- {
- public static Indexer build()
- {
- return new IndexerImpl();
- }
-
- public static <T> T decorateIndexer(Class<T> serviceInterface, T delegate,
- String serviceId, Log serviceLog,
-
- @InjectService("LoggingDecorator")
- LoggingDecorator decorator)
- {
- return decorator.build(serviceInterface, delegate, serviceId, serviceLog);
- }
- }
decorateIndexer()方法是一个服务装饰器方法因为它以单词“decorate”开头。在这个简单的案例中,只用myapp.Indexer服务将被装饰,即使如果有其他服务在这个模块或其他的当中。这是因为名称匹配("decorateIndexer" 和 "buildIndexer"),但我们将很快看到标注如何可以被用来为装饰定位很多服务。
这里我们使用参数化类型(<T>),以加强委派对象传递在(那将是核心服务实现,或某些其他拦截器)必须实现的服务接口内,并且那个装饰器方法必须返回该服务接口实例的行为。
可以被提供给装饰器方法的值与给构造器方法的完全一样,增加一个:根基服务将被传递在内作为一个java.lang.Object类型对象。为了这个目的,一个装饰器方法必须有一个java.lang.Object类型参数。
在上面的例子中,装饰器方法接收核心服务实现,service接口为Indexer服务,Log接口为Indexer服务,然后一个拦截器工厂产生日志拦截器。
“heavy lifting”通过工厂被提供,将创建一个新的拦截器在委派给核心服务实现之前记录方法进入。这个拦截器也将记录方法参数,返回值,甚至记录异常。
方法返回值是一个新的拦截器。你可以返回null如果你的装饰器方法决定不再装饰这个提供的服务。
当然,绝不阻止你从结合building与decorating在服务构建器方法内。
- package org.example.myapp.services;
-
- import org.apache.tapestry.ioc.services.LoggingDecorator;
-
- public class MyAppModule
- {
- public static Indexer build(Class serviceInterface, Log serviceLog,
- @InjectService("LoggingDecorator")
- LoggingInterceptorFactory decorator)
- {
- return decorator.build(serviceInterface, serviceLog, new IndexerImpl());
- }
- }
但是我们也将看到,它可能有一个单独的装饰器方法通过使用标注工作在很多不同服务上。
确定Targetting Multiple Services
通过使用@Match标注,你可以标识哪个服务被装饰。
指定在Match标注内的值是一个或多个样式。这些样式被用来匹配服务。在一个样式内,一个"*"在一个字符串开头或末尾匹配零或多个字符。
例如,瞄准所有在你模块中的服务。
- @Match("*")
- public static <T> T decorateLogging(Class<T> serviceInterface, T delegate,
- String serviceId, Log serviceLog,
- @InjectService("LoggingDecorator")
- LoggingDecorator decorator)
- {
- return decorator.build(serviceInterface, delegate, serviceId, serviceLog);
- }
你可以通过@Match使用多个样式,在一个方案内,装饰器将被应用给任何匹配样式的服务。例如,如果你只想为你的数据访问和业务逻辑服务进行记录。你应该用@Match("Data*", "*Logic")(当然,这都基于你如何命名你的服务了)。
就像例子中显示的,一个简单的“块”匹配被支持,可以使用一个星号('*')在匹配的字符串开头或末尾以匹配多个字符,忽略大小写差异。
因而,@Match(*)是危险的,因为它将匹配你所有模块中所有服务。
注:它不会装饰TapestryIOCModule服务。
注:另外一个匹配服务的方法: 基于服务接口的继承或基于现场的标注在这个服务接口上的特殊类。这一点没有实现,但可轻易完成在装饰方法内(如果它决定该服务不需要装饰将返回null)。
装饰器排序
万一有多个装饰器应用在一个单独的服务上,你可以在装饰器上应用附加的标注@Order来控制顺序。
这个标注允许对装饰器指定多个顺序约束,相对其它装饰器的顺序。
例如,你总是希望第一个应用的是日志装饰器,所以:
- @Match("*")
- @Order("before:*")
- public static <T> T decorateLogging(Class<T> serviceInterface, T delegate,
- String serviceId, Log serviceLog,
- @InjectService("LoggingDecorator")
- LoggingDecorator decorator)
- {
- return decorator.build(serviceInterface, delegate, serviceId, serviceLog);
- }
"before:*"指出这个装饰器应该在任何模块的任何装饰器之前出现。
分享到:
- 2007-05-25 10:19
- 浏览 1836
- 评论(1)
- 论坛回复 / 浏览 (0 / 2471)
- 查看更多
相关推荐
在Tapestry中,IOC容器负责管理对象的生命周期和依赖关系,包括安全相关的服务。 在Tapestry 5.3.5中,实现用户登录权限通常涉及以下几个关键知识点: 1. **身份验证服务**:这是处理用户身份验证的核心组件。通常...
在"tapestry-ioc-5.0.3-src"这个压缩包中,我们可能找到Tapestry IOC框架的源代码,这对于开发者深入理解其工作原理和定制功能非常有价值。 1. **依赖注入(DI)**:Tapestry IOC的核心概念就是DI,它允许对象在...
1. **Tapestry Core**: 这是Tapestry框架的基础部分,包含了核心组件、服务容器(Tapestry IoC)和页面生命周期管理。通过源码分析,我们可以理解其如何实现页面组件的渲染、事件处理和依赖注入。 2. **Tapestry ...
2. **tapestry-ioc.jar**:Tapestry依赖注入(IoC)容器,用于管理对象的创建、配置和生命周期,使得代码更加松耦合。 3. **tapestry-webresources.jar**:处理静态资源如CSS、JavaScript和图片,支持压缩、合并和...
4. **Tapestry IoC (Inversion of Control)**:`tapestry-ioc-5.3.8.jar`实现了依赖注入容器,使得对象的创建和管理变得更加简单,同时也促进了代码的解耦。开发者可以声明服务并定义它们之间的依赖关系,IoC容器会...
<tapestry:propertySelection name="country" label="Country" model="${countries}" /> ``` **14. Table组件:** - **用途:**用于创建表格。 - **示例代码:** ```xml <tapestry:table data-model="${users}...
这个压缩包包含了多个以"Tapestry"开头的子文件,如 "tapestry-core", "tapestry-hibernate", "tapestry-ioc", "tapestry-upload", 和 "tapestry-spring",这些都是Tapestry框架的不同模块或插件。这些文件的后缀是...
"tapestry学习入门资料" Tapestry 是一个开源的基于 servlet 的应用程序框架,它使用组件对象模型来创建动态的、交互的 web 应用。 Tapestry 使得 Java 代码与 HTML 完全分离,利用这个框架开发大型应用变得...
《Tapestry 5.0:构建Web应用程序》是一份专为深入了解Tapestry 5.0框架而准备的详细指南。Tapestry是Apache软件基金会的一个开源项目,它提供了一种基于Java的声明式MVC(Model-View-Controller)框架,用于构建...
- **tapestry-ioc**:Tapestry 的依赖注入和服务容器模块,是Tapestry的核心组件之一。 - **tapestry-tutorial1**:可能是一个示例教程项目,帮助开发者学习和理解Tapestry的基本用法。 - **tapestry-annotations*...
4. **tapestry-ioc-LICENSE.txt**:这部分涉及Tapestry的依赖注入(IOC)框架,它是Tapestry实现组件之间解耦的关键部分。 5. **tapestry-upload-LICENSE.txt**:关于Tapestry中文件上传功能的许可信息,帮助开发者...
6. **Spring集成**:通过tapestry-spring模块,Tapestry可以与Spring框架协同工作,利用Spring的IoC容器管理服务和bean。 7. **测试支持**:Tapestry-test模块提供了专门的测试工具,使得开发者能够对组件进行单元...
- **实现方式**: 通过`<tapestry:link>`标签或`<tapestry:component>`中的`href`属性来实现页面间的跳转。 - **应用场景**: 用户操作后导航到新的页面。 **1.3 初始化** - **初始化方法**: `init()`方法是在组件...
Tapestry是一款强大的Java Web应用程序框架,由Apache软件基金会维护,它强调了组件化、模块化和可重用性,使得开发复杂的Web应用变得更加简单。本文将深入介绍Tapestry 4的相关知识点。 1. **组件化编程**: ...
### Tapestry5:构建Web应用程序 #### 一、Tapestry5概述 Tapestry5是一种先进的、基于Java的Web开发框架,它以其强大的功能、灵活性以及易用性著称。该框架由Howard Lewis Ship创建,并由Apache软件基金会维护。...
然而,随着时间的推移,Tapestry4展现出的独特优势逐渐显现,尤其是其通过Hivemind提供的IoC和DI(Dependency Injection)机制,使得开发者能够根据具体需求重构Tapestry4的组件,从而实现更为个性化、符合特定场景的...
《Tapestry 5:构建Web应用程序》是关于Tapestry 5框架的一本权威指南。Tapestry 5是一个强大的Java Web应用框架,由Apache软件基金会开发并维护,它致力于提供一种更高效、更优雅的方式来构建动态、交互式的Web应用...
Tapestry是一个分布式系统基础设施,专门设计用于实现容错性的广域定位和路由。这个系统由Ben Y. Zhao、John Kubiatowicz和Anthony D. Joseph等人在加州大学伯克利分校的计算机科学部开发,旨在应对无处不在计算的...
Tapestry IOC(Inversion of Control)容器,如`tapestry-ioc-5.3.7.jar`,是Tapestry框架的重要组成部分,负责服务的创建、管理和依赖注入。它使得组件之间的依赖关系可以通过配置文件进行管理,而不是硬编码在类...