SeamFramework.orgCommunity Documentation

第 5 章 范围和上下文

5.1. 范围类型
5.2. 内置范围
5.3. 对话范围
5.3.1. 对话划分
5.3.2. 对话的传播
5.3.3. 对话超时
5.4. 依赖的伪范围
5.4.1. @New注释

目前为止,我们已经看到了几个 范围类型注释的例子。Web Bean的范围决定了Web Bean实例的生命周期。范围还决定了哪个客户端引用了哪个Web Bean实例。根据Web Beans规范,一个范围决定:

  • 该范围的Web Bean的一个实例何时被创建

  • 该范围的Web Bean实例何时被销毁

  • 注入的引用指向该范围的Web Bean的哪个实例

例如,如果我们有一个会话范围的Web Bean:CurrentUser。那么在同一个HttpSession的上下文中调用的所有的Web Bean都将看到同一个CurrentUser实例。这个实例在会话第一次需要CurrentUser时被自动创建,在会话结束时被自动销毁。

Web Bean有一个特性是可扩展的上下文模型。我们可以创建一个新的范围类型注释来定一个新的范围:

@Retention(RUNTIME)

@Target({TYPE, METHOD})
@ScopeType
public @interface ClusterScoped {}

当然,这是这项工作最简单的部分。为了让这个范围类型可以使用,我们还需要定义一个Context(上下文)对象来实现这个范围!实现上下文通常是一个非常具备挑战的技术任务,这常常只能由开发编程框架的专家完成。

我们可以在Web Bean实现类中应用范围类型注释来指定Web Bean的范围:

@ClusterScoped

public class SecondLevelCache { ... }

通常,你将会使用一个Web Bean内置的范围。

Web Beans定义了四个内置范围:

对于使用Web Beans的Web应用:

在下列情况下请求和应用范围是激活的:

如果应用试图调用一个Web Bean,而对应的范围上下文没有处于激活状态时,Web Bean管理器在运行时将抛出一个ContextNotActiveException异常。

这四个内置范围的其中三个对于每个Java EE程序员来说都非常熟悉,所以让我们别浪费时间来讨论他们。不过有一个范围是新的。

Web Beans的对话(Conversation)范围有点类似与传统的会话范围(Session),传统的会话范围常常用来存储和系统用户相关的状态,并且能够跨越多个请求。然而,对话范围还有很多地方和会话范围不一样:

从用户角度出发,一个对话代表一个任务,或者一个工作单元。用户当前工作相关的状态由对话上下文维护。如果用户同时处理多个事情,就会有多个对话与之对应。

一个对话上下文在任何JSF请求中都是激活的。但是,大部分对话都在请求结束的时候被销毁了。如果一个对话需要跨越多个请求来维护状态的话,它必须显式地升级为长时对话

除了内置的四个范围,Web Beans还提供了一个依赖的伪范围。这个范围是没有显式设置范围类型的Web Bean的默认范围。

例如,这个Web Bean有一个范围类型@Dependent:

public class Calculator { ... }

当一个注入点被解析为一个依赖的Web Bean之后,每当第一个Web Bean被初始化时,都会创建一个依赖的Web Bean实例。不同的Web Beans或者不同的注入点的依赖的Web Beans的实例都不会被共享。它们是其它Web Bean实例的依赖的对象

依赖的Web Bean实例在它们所依赖对象实例销毁的时候被销毁。

Web Bean能够让我们轻松获得一个Java类或者EJB Bean的依赖实例,甚至这个类或者EJB Bean已经被声明为一个其他范围的Web Bean也没问题。