双向注入
Dependency injection(依赖注入) 和 inversion of control(控制反转) 现在对大多数Java 开发者来说都是熟悉的概念了。依赖注入允许一个组件通过容器“注入”另一个组件到一个setter方法或者实例变量的方式,来获得被“注入”组件的引用 (reference)。我们之前看过的所有依赖注入的实现,注入发生在组件创建的时候,在此后实例的整个生命周期中不再改变。对无状态组件,这么做是有道理的。从客户端的角度来看,特定种类的无状态组件的所有实例都是可以替换的。另一方面,Seam着重处理有状态组件。此时传统的依赖注入不再是非常有效了。Seam引入了 bijection(双向注入) 这个名词,用来作为注入的广义概括。和injection(单向注入)对比,bijection是:
*
contextual(上下文相关的) - 双向注入用来针对不同的上下文来组装有状态组件(在较大范围的上下文中的组件,可以引用较小范围上下文中的组件)
*
bidirectional(双向的) - 被触发后,值从上下文变量中注射到组件属性中,也可以从组件属性outjected(反向注入) 回上下文,这样被调用的组件可以只通过改写自己的实例变量就同时操作了上下文变量的值
*
dynamic(动态的) - 因为上下文变量的值随着时间不断改变,而且因为Seam组件是有状态的,双向注入在每次组件被调用的时候都发生。
基本上,通过设置实例变量是需要注入、反向注入、还是二者皆是,双向注入让你将上下文变量映射到组件实例变量。当然,我们使用注解来设置双向注入。
@In 注解指明应该注入值,可能是注入实例变量:
@Name("loginAction")
@Stateless
public class LoginAction implements Login {
@In User user;
...
}
或者注入setter方法:
@Name("loginAction")
@Stateless
public class LoginAction implements Login {
User user;
@In
public void setUser(User user) {
this.user=user;
}
...
}
默认情况下,针对被注入的属性或者实例变量名, Seam会对所有的上下文进行优先级搜索。 如果你希望明确指定上下文变量名,可以这样写:@In("currentUser")。
如果没有组件实例绑定到具名的上下文变量,你可能希望Seam创建一个,你可以指定 @In(create=true)。 如果值是可选的(可以为null),请指定 @In(required=false)。
对于某些组件,到处指定 @In(create=true) 是很繁琐的。 你可以注解整个组件为 @AutoCreate,它就会在任何需要的时候自动创建,不需要明确的指定 create=true。
你还可以注入表达式的值:
@Name("loginAction")
@Stateless
public class LoginAction implements Login {
@In("#{user.username}") String username;
...
}
(在下一章,有更多的关于组件生命周期和注射的内容。)
@Out 注解指定了某个属性需要对外注入,可能是从实例变量:
@Name("loginAction")
@Stateless
public class LoginAction implements Login {
@Out User user;
...
}
或者从某个getter方法:
@Name("loginAction")
@Stateless
@Interceptors(SeamInterceptor.class)
public class LoginAction implements Login {
User user;
@Out
public User getUser() {
return user;
}
...
}
属性可以既是被注入的,也可以对外注入:
@Name("loginAction")
@Stateless
public class LoginAction implements Login {
@In @Out User user;
...
}
或者:
@Name("loginAction")
@Stateless
public class LoginAction implements Login {
User user;
@In
public void setUser(User user) {
this.user=user;
}
@Out
public User getUser() {
return user;
}
...
}
---------------------------------------------------------------------------------------------------------------------------
Factory和Manager组件
我们经常需要与非Seam组件的对象打交道。但是我们仍然希望把它们通过 @In 注入我们的组件,并在值和方法表达式中使用它们。 有时候,我们甚至需要把它们绑定到Seam 上下文的生命周期里(例如@Destroy)。 所以Seam上下文可以容纳非Seam组件的对象,并且Seam提供了一些很好的特性,这些特性使得我们与绑定到上下文里的非组件对象打交道更加容易。
factory component pattern(工厂组件模式)让Seam组件作为非组件对象的构造器。 当上下文变量被引用,但是没有值被绑定到它时,会调用一个factory method(工厂方法)。 我们通过@Factory注解来定义工厂方法。 工厂方法把一个值绑定到上述上下文变量,并且决定被绑定的值的范围。有两种工厂方法。第一种返回一个值,Seam会把它绑定到上下文里:
@Factory(scope=CONVERSATION)
public List<Customer> getCustomerList() {
return ... ;
}
第二种方法返回 void,它自己把值绑定到上下文变量:
@DataModel List<Customer> customerList;
@Factory("customerList")
public void initCustomerList() {
customerList = ... ;
}
两种情况下,当我们引用 customerList 上下文变量,而其值为null时,工厂方法被调用,然后对这个值生命周期的其他部分就无法操纵了。 更加强大的模式是 manager component pattern(管理者组件模式)。 在这种情况下,有一个Seam组件绑定到上下文变量,它管理着上下文变量的值,对客户端不可见。
管理者组件可以是任何组件,它需要一个 @Unwrap 方法。 该方法返回对客户端可见的值,每次 上下文变量被引用的时候都会被调用。
@Name("customerList")
@Scope(CONVERSATION)
public class CustomerListManager
{
...
@Unwrap
public List<Customer> getCustomerList() {
return ... ;
}
}
当你有一个对象并需要对其组件的生命周期更多的控制时,管理组件模式就显得尤其有用。 例如,如果你有一个重量级的对象,当上下文结束时你想对其进行清除操作,你可以@Unwrap对象,并在管理组件的 @Destroy 方法中执行清除操作。
@Name("hens")
@Scope(APPLICATION)
public class HenHouse {
Set<Hen> hens;
@In(required=false) Hen hen;
@Unwrap
public List<Hen> getHens() {
if (hens == null) {
// Setup our hens
}
return hens;
}
@Observer({"chickBorn", "chickenBoughtAtMarket"})
public addHen() {
hens.add(hen);
}
@Observer("chickenSoldAtMarket")
public removeHen() {
hens.remove(hen);
}
@Observer("foxGetsIn")
public removeAllHens() {
hens.clear();
}
...
}
这里,被管理的组件观察那些改变在下面的对象的事件。组件自己管理这些动作,并且由于对象在每一次访问中都被解开,所以这里提供了一个统一的视图。
分享到:
相关推荐
这个名为"Seam-Carving-Matlab-master.rar_boardkkc_seam_seam carving_seamca"的压缩包文件包含了Matlab实现的Seam Carving算法,非常适合学习和理解这一技术。 Seam Carving的基本思想是找到图像中的一条或几条...
Seam - 语境相关的组件[满江红20071230]............................................................................................................................ 1 Java EE 框架...........................
文件"Seam - 语境相关的组件.pdf"很可能是Seam框架深入学习的教程或指南,涵盖了上述概念的详细解释和示例。通过阅读这份资料,你应该能掌握Seam框架如何利用语境相关的组件来优化Java EE应用的开发,以及如何在实际...
- **实现方式**:通过依赖注入 (DI) 和其他机制,Seam 能够自动管理对象的创建和生命周期,从而降低了组件间的耦合度。 6. **对话:Seam 的工作单元 (The Conversation: Seam's Unit of Work)** - **对话概念**...
Algorithm-seam-carving-js.zip,seam-carver的javascript实现。seam carver是一种基于内容的图像缩放算法,算法是为计算机程序高效、彻底地完成任务而创建的一组详细的准则。
Seam Carving作为其中的一个重要组成部分,因其在保留图像内容和细节上的优势,而被广泛应用于图像编辑软件和多媒体应用中。理解并掌握Seam Carving不仅可以提升在图像处理领域的专业技能,也为开发创新的图像编辑...
3. **注入(Injection)**: Seam支持依赖注入,可以将一个组件的实例自动注入到其他组件中,无需手动创建对象或管理依赖关系。 4. **导航和流程控制(Navigation and Flow Control)**: Seam提供了强大的导航机制,...
- **组件和依赖注入**: - Seam 组件既可以是 POJO 也可以是 EJB。 - 支持依赖注入(DI)和反向依赖注入(BI)。 - 支持配置异常处理和注解。 - **会话范围**:会话范围是 Seam 的一个重要特性,它允许组件保持...
2007年Shai Avidan 和Ariel Shamir论文《Seam Carving for Content-Aware Image Resizing》所提出方法的Matlab代码实现和作者的论文。 效果非常炫,而且代码不长
Seam Carving,又称为Seam Carving,是一种图像处理技术,主要用于图像的无损缩放和对象删除。这项技术的核心在于通过寻找能量最小的“接缝”(seams)来调整图像的尺寸,同时尽可能地保持图像的整体视觉效果。在...
在开始使用之前,确保已经安装了 Seam 工具包,其中包含了 seam 和 seam.bat 脚本,分别适用于 Linux/Unix 和 Windows 系统。要查看 Seam-gen 的帮助信息,只需在命令行中输入 `seam help`。 生成项目骨架的基本...
通过使用POJOs处理JSF事件和实现双向依赖注入,Seam为开发者带来了更加直观和灵活的编程体验。对于需要构建大型、复杂的企业级应用的团队来说,JBoss Seam无疑是一个值得考虑的优秀框架。通过深入理解和熟练运用Seam...
通过学习和理解Seam,开发者可以更有效地构建可扩展、可维护的Java EE应用,利用其强大的上下文相关组件模型和事件驱动架构,提高开发效率,减少代码的复杂性。无论是对于企业级应用开发还是个人项目,Seam都是一个...
1. **Seam架构**:理解Seam如何将组件、事件和依赖注入结合在一起,提供统一的编程模型。 2. **JSF集成**:学习如何利用Seam增强JSF,实现更强大的用户界面交互。 3. **EJB 3.0集成**:探讨Seam如何简化EJB的使用,...
java jboss seam jboss-seam-selectitems
2. **组件添加**:通过`seam component`命令,可以方便地将Seam组件添加到项目中,如EJB、JSF等。 3. **自动构建**:支持Maven集成,可以使用`seam build`进行项目的自动化构建。 4. **部署与运行**:`seam deploy`...
而`seam-gen`命令作为Seam框架的一个重要组成部分,主要用于自动生成Seam项目的基本结构和代码模板,帮助开发者快速搭建起开发环境。 `seam-gen`命令的工作原理类似于Ruby语言中的“scaffold”概念,它通过一系列预...
JBoss Seam是一个开源的Java EE框架,它通过依赖注入和会话模型,简化了基于Java EE的企业级应用开发。Seam框架为开发者提供了一个集成化的环境,其中整合了多种技术规范,比如EJB3、JSF、JPA、SessionBean、MDB和...