`
chinajavawolf
  • 浏览: 116798 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

(C2)Tapestry IoC:Tapestry IoC Modules

阅读更多
本人翻译目的是用来学习Tapestry5的,共享出来希望大家批评指正。计划持续翻译。
chinajavawolf  
Tapestry IoC 模块
你通过提供一个模块构建器类通知Tapestry关于你的服务和贡献。
 
这个模块构建器是一个简单Java类。一个标注系统和命名约定允许Tapestry决定什么服务被这个模块提供。
 
一个模块构建器定义构建器方法,一个被模块提供给每个服务的方法。
 
服务构建器方法是公用方法。它们通常是静态的。这是一个普通例子:
 
  1. package org.example.myapp.services;   
  2.     
  3. public class MyAppModule   
  4. {   
  5.  public static Indexer build()   
  6.  {   
  7.     return new IndexerImpl();   
  8.  }   
  9. }   
 
任何名字以“build”开头的公用方法(静态或实例)是一个服务构建器方法,在模块内隐含定义了一个服务。
 
这里我们定义一个服务在Indexer服务接口的周围(大概也在org.example.myapp.services包里)。
 
每个服务都有一个唯一的id,用来在整个服务注册库(Registry)内标识它(这个Registry是来自所有模块的所有服务的集合)。如果你不能提供一个明确的服务id,象在这个例子里一样,这个服务id从返回类型提取:这个服务有一个id是“Indexer”。
 
你能够给服务一个明确的id通过添加它到方法名:buildIndexer()。这是有益的,当你不想服务id匹配这个服务接口名(例如,当你有实现同一接口的不同服务时)时,或者当你需要避免方法名冲突时(Java 只允许一个唯一的方法使用一个给定的名字和设置的参数,即使返回类型是不同的,因此如果你有两个不同的服务构建器方法使用同样的参数,你应该给他们明确的服务ids在同一方法名内)。
 
Tapestry IoC是不区分大小写的;稍后我们可以使用“indexer”或“INDEXER”或任何其中的一种变化来查阅这个服务。
 
服务的ids必需是唯一的;如果另一个模块也贡献一个id为“Indexer”(或任何一种变形)的服务,当注册库被创建时一个运行时异常将发生。
 
我们能够扩展这个例子通过增加额外的服务构建器方法,或者通过显示注入依赖。更详细的看这个服务文档
Autobuilding 服务
一个替代方法,并且通常是首选的方法,该方法是经由模块的bind()方法定义一个服务。先前的例子可以被重写成这样:
  1. package org.example.myapp.services;   
  2.     
  3. import org.apache.tapestry.ioc.ServiceBinder;   
  4.     
  5. public class MyAppModule   
  6. {   
  7.  public static void bind(ServiceBinder binder)   
  8.  {   
  9.      binder.bind(Indexer.class, IndexerImpl.class);   
  10.  }   
  11. }   
The service documentation goes into much greater detail about autobuilding of services. In most cases, autobuilding is the preferred approach.
这个服务文档对于autobuilding服务更深入更详细。在大多数情形下,autobuilding是首选方法。
 
Cacheing 服务
 
你将经常发现你自己多次的注入相同服务在你的服务构建器或服务装饰方法上。这可能是相当多余的键入。少的代码就是好的代码,只要一个选择,你可以定义一个构造器给你的模块以接收标注的参数(与使用服务构建器注入一样)。
 
这给你一个机会去存储共同的服务在实例变量里,为稍后在服务构建器方法中使用。
 
  1. public class MyModule   
  2. {      
  3.  private final JobScheduler _scheduler;   
  4.  private final FileSystem _fileSystem;   
  5.     
  6.  public MyModule(JobScheduler scheduler, FileSystem fileSystem)   
  7.  {   
  8.     _scheduler = scheduler;   
  9.     _fileSystem = fileSystem;   
  10.  }   
  11.     
  12.  public Indexer build()   
  13.  {   
  14.     IndexerImpl indexer = new IndexerImpl(_fileSystem);   
  15.          
  16.     _scheduler.scheduleDailyJob(indexer);   
  17.          
  18.     return indexer;   
  19.  }   
  20. }   
 
注意我们已经从静态方法转变到实例方法。因为builder方法不是静态的,MyModule类将被实例化以此来调用这个方法。这个构造器接收两个普通的依赖,他们被存储在实例字段域内可以稍后被用在服务构建器方法buildIndexer()内。
 
这种方法不是必需的,如果你愿意所有你的模块的builder方法都可以是静态的。当你有很多普通的依赖并且希望消除作为给多个模块参数所定义的那些依赖时它被使用。
 
Tapestry IoC自动解决参数类型(例子中的,JobScheduler和FileSystem)对应的实现那个类型的服务。当有不少于一个实现这个服务接口的服务时,你将得到一个错误(但是附加的标注河配置可以被用来确保正确的服务被注入)。
 
对于模块,有两个可以被提供给这个模块实例的附加参数类型被用来查阅资源(优于注入服务)。
 
1.       org.apache.commons.logging.Log:日志对于模块(来自这个模块的类名)。
2.          ObjectLocator:访问其他服务。
 
注意,那个这段域是final的:这很重要。Tapestry IoC是线程安全的,你基本上不用考虑并发问题。但在一个繁忙的应用中,不同的服务可能被不同的线程在同时创建。每个模块构建器类最多被实例化一次,并且这些字段域为final,以保证他们的值可以有效的在多个线程内穿越。可以查阅Brian GoetzJava并发实践,有较完整的关于final字段域,构造器和线程之间关系的探究... 或者就信任我们!
 
应该注意这种方法:在一些情况下,你可以强制这样一种情形,即这个模块的构造器依赖自身。例如,如果你调用一个方法在任何注入的服务上,该服务是定义在来自这个模块构建器的构造器的同一模块内部的服务,那么这个服务的实现将是必需的。
 
Tapestry发现这些情况然后抛出一个运行时异常以防止死循环。
 
自动加载模块
 
当设置注册库时,Tapestry可以自动查找打包在JARs内的模块。这么做是通过搜索一个明确目标的清单(manifest)条目。
 
这个清单的条目名是“Tapestry-Module-Classes”。这个值是一个逗号分隔的模块构建器类的完整类名列表(这允许一个单独的JAR可以包含多个相关的模块)。忽略空格。
 
例如:
  1. Manifest-Version: 1.0  
  2. Tapestry-Module-Classes:org.example.mylib.LibModule, org.example.mylib.internal.InternalModule   
  3.     
如果你使用Maven2,那么获得这些你的JAR的清单条目和配置在你的pom.xml中一样简单。
 
  1. <project>   
  2.  . . .   
  3.  <build>   
  4.     <plugins>   
  5.       <plugin>   
  6.         <groupId>org.apache.maven.plugins</groupId>   
  7.         <artifactId>maven-jar-plugin</artifactId>   
  8.         <configuration>   
  9.           <archive>   
  10.             <manifestEntries>   
  11.               <Tapestry-Module-Classes>org.example.mylib.LibModule,    
  12.                 org.example.mylib.internal.InternalModule</Tapestry-Module-Classes>   
  13.             </manifestEntries>   
  14.           </archive>   
  15.         </configuration>   
  16.       </plugin>   
  17.     </plugins>   
  18.  </build>   
  19.  . . .   
  20. </project>   
 
更详细的内容在Maven Manifest指南内提供。
 
SubModule 标注
 
通常你会需要几个不同的模块一起工作,那么你应该作为一个整体加载他们。
 
办法之一是更新这个清单中的模块ids,表现为先前的扩展。
 
事实上重新做时,这将变得冗长乏味,并且极其脆弱(比如,类或包的重命名)。
 
一个好的替代方法是@SubModule标注
 
这个标住的值是被加工为模块构建器类的附加类的列表,完全就像他们被定义在清单内一样。
 
例如:
  1. @SubModule(   
  2. { InternalTransformModule.class })   
  3. public final class InternalModule   
  4. {   
  5.  . . .  
 
通常,你应该只需要定义一个单独模块在JAR清单内,并且使用@SubModule添加任何附加的模块构建器类。
 
模块构建器实现注意
 
模块构建器类被设计成非常非常简单的实现。
 
另外,保持方法非常简单。使用参数注入获得你需要的依赖的访问。
 
小心继承。Tapestry将留意所有public方法,即使这些方法继承基类。Tapestry眼中只有public方法。
 
通过约定,模块构建器类的名字为模块名和final类名构成。
 
你不用必需定义你的方法为静态的。使用静态方法只是在少数情况是绝对必需的,当构造器是依赖来自同一模块的贡献时(这将引起先有鸡还是先有蛋的争论(chicken-and-egg)情形,通过静态方法将彻底避免)
分享到:
评论

相关推荐

    tapestry5.3.5 IOC用户登陆权限

    在Tapestry中,IOC容器负责管理对象的生命周期和依赖关系,包括安全相关的服务。 在Tapestry 5.3.5中,实现用户登录权限通常涉及以下几个关键知识点: 1. **身份验证服务**:这是处理用户身份验证的核心组件。通常...

    tapestry-ioc-5.0.3-src

    在"tapestry-ioc-5.0.3-src"这个压缩包中,我们可能找到Tapestry IOC框架的源代码,这对于开发者深入理解其工作原理和定制功能非常有价值。 1. **依赖注入(DI)**:Tapestry IOC的核心概念就是DI,它允许对象在...

    tapestry源码 api等

    1. **Tapestry Core**: 这是Tapestry框架的基础部分,包含了核心组件、服务容器(Tapestry IoC)和页面生命周期管理。通过源码分析,我们可以理解其如何实现页面组件的渲染、事件处理和依赖注入。 2. **Tapestry ...

    Tapestry 5.4.1 相关jar文件

    2. **tapestry-ioc.jar**:Tapestry依赖注入(IoC)容器,用于管理对象的创建、配置和生命周期,使得代码更加松耦合。 3. **tapestry-webresources.jar**:处理静态资源如CSS、JavaScript和图片,支持压缩、合并和...

    apache-tapestry-5.3.8-bin.zip

    4. **Tapestry IoC (Inversion of Control)**:`tapestry-ioc-5.3.8.jar`实现了依赖注入容器,使得对象的创建和管理变得更加简单,同时也促进了代码的解耦。开发者可以声明服务并定义它们之间的依赖关系,IoC容器会...

    优化大使tapestry-bin-5.0.18.zip

    这个压缩包包含了多个以"Tapestry"开头的子文件,如 "tapestry-core", "tapestry-hibernate", "tapestry-ioc", "tapestry-upload", 和 "tapestry-spring",这些都是Tapestry框架的不同模块或插件。这些文件的后缀是...

    Tapestry5.0.7

    - **tapestry-ioc**:Tapestry 的依赖注入和服务容器模块,是Tapestry的核心组件之一。 - **tapestry-tutorial1**:可能是一个示例教程项目,帮助开发者学习和理解Tapestry的基本用法。 - **tapestry-annotations*...

    tapestry-bin-5.1.0.5

    4. **tapestry-ioc-LICENSE.txt**:这部分涉及Tapestry的依赖注入(IOC)框架,它是Tapestry实现组件之间解耦的关键部分。 5. **tapestry-upload-LICENSE.txt**:关于Tapestry中文件上传功能的许可信息,帮助开发者...

    tapestry5.2.6 jar包

    6. **Spring集成**:通过tapestry-spring模块,Tapestry可以与Spring框架协同工作,利用Spring的IoC容器管理服务和bean。 7. **测试支持**:Tapestry-test模块提供了专门的测试工具,使得开发者能够对组件进行单元...

    Tapestry4开发指南

    然而,随着时间的推移,Tapestry4展现出的独特优势逐渐显现,尤其是其通过Hivemind提供的IoC和DI(Dependency Injection)机制,使得开发者能够根据具体需求重构Tapestry4的组件,从而实现更为个性化、符合特定场景的...

    apache-tapestry-5.3.7-bin.zip

    Tapestry IOC(Inversion of Control)容器,如`tapestry-ioc-5.3.7.jar`,是Tapestry框架的重要组成部分,负责服务的创建、管理和依赖注入。它使得组件之间的依赖关系可以通过配置文件进行管理,而不是硬编码在类...

    Tapestry 5 電子書

    此外,书中还会涉及依赖注入(Dependency Injection,DI)和控制反转(Inversion of Control,IoC)的概念,这是Tapestry 5实现松耦合和可测试性的关键。读者将学习如何使用Tapestry的IoC容器来管理对象的生命周期和...

    基于Tapestry+Spring+Hibernate框架的Web应用

    Spring框架是一个轻量级的控制反转(Inversion of Control, IoC)和面向切面编程(Aspect Oriented Programming, AOP)容器。Spring的核心功能之一是依赖注入(Dependency Injection, DI),它使得组件之间的耦合度...

    Tapestry 5.1 实例教程

    首先创建一个简单的页面类,继承自`tapestry-ioc:Component`,并定义一个名为`index`的页面。然后创建对应的HTML模板文件,声明页面组件和属性。 #### 3.3 运行应用 通过Maven的`jetty:run`目标启动内置的Jetty...

    tapestry-bin-5.0.14.zip

    - “tapestry-ioc”是Tapestry的依赖注入(IOC)容器,它简化了服务和组件之间的依赖关系管理,使得代码更加解耦合和可测试。 - “tapestry-upload”处理文件上传功能,提供了处理大文件、多文件上传的工具和支持,...

    tapestry 源码

    3. **tapestry-ioc**:IoC(Inversion of Control)或依赖注入是Tapestry的重要组成部分,它简化了对象之间的依赖关系管理。源码分析可以帮助开发者了解如何定义服务,以及如何通过依赖注入来解耦组件。 4. **...

Global site tag (gtag.js) - Google Analytics