Seam 组件
Seam 组件是POJO(Plain Old Java Objects)。特别地,他们是JavaBean或者EJB 3.0 enterprise bean。Seam并不强求组件是EJB,甚至可以不使用EJB 3.0兼容的容器,Seam在设计的时候处处考虑对EJB 3.0的支持,并且包含对EJB 3.0的深度整合。
*
EJB 3.0 stateless Session Beans
*
EJB 3.0 stateful Session Beans
*
EJB 3.0 entity beans
*
JavaBeans
*
EJB 3.0 message-driven beans
(1)无状态Session Bean
无状态Session Bean组件无法在多次调用之间保持状态。因此,它们通常在不同的Seam上下文中,操作其他组件的状态。他们可以作为JSF的action listener,但是不能为JSF组件的显示提供属性。
因为每次请求都产生一个新的实例,无状态session bean可以并发访问。把其实例和请求相关联是EJB3容器的责任(通常这些实例会从一个可重用的池中分配,所以你可能会发现某些实例变量还保存着上次使用的痕迹。)
无状态Session Bean总是生活在无状态上下文中。
无状态Session Bean是Seam组件中最没趣的了。
Seam无状态Session Bean组件可以使用 Component.getInstance() 或者 @In(create=true) 实例化。它们不能直接使用JNDI或者 new 操作实例化。
(2)有状态Session Bean
有状态Session Bean不仅可以在bean的多次调用之间保持状态,而且在多次请求之间也可以保持状态。不由数据库保存的状态通常应该由有状态Session Bean保持。这是Seam和其他web框架之间的一个显著的不同点。其他框架把当前会话的信息直接保存在 HttpSession 中,而在Seam中你应该把它们保存在有状态Session Bean的实例中,该实例被绑定到会话上下文。这可以让Seam来替你管理状态的生命周期,并且保证在多个不同的并发会话中没有状态冲突。
有状态Session Bean经常被作为JSF action listener使用,也可以作为JSF显示或者form提交的backing bean(支持bean ,或称后台bean),提供属性供组件访问。
默认情况下,有状态Session Bean会被绑定到Conversation Context。它们绝不会绑定到page或stateless context。
对Session范围的有状态Session Bean的并发请求,会被Seam按顺序串行处理。
Seam有状态Session Bean组件可以使用 Component.getInstance() 或者 @In(create=true) 实例化。它们不能直接使用JNDI或者 new 操作实例化。
(3) 实体Bean
实体Bean可以被绑定到上下文变量,起到Seam组件的作用。因为Entity除了上下文标识之外,还有持久标识,Entity实体通常明确的由Java Code绑定,而非由Seam隐性初始化。
Entity Bean实体不支持双向注入或者上下文划分。对Entity Bean的调用也不会触发验证。
Entity Bean通常不作为JSF的action listener使用,但经常作为JSF组件用于显示或者form提交的后台bean,提供属性功能。特别是,当Entity作为后台Bean的时候,它会和一个无状态Session Bean扮演的action listener联用,来实现CRUD之类的功能。
默认情况下,Entity Bean被绑定到Conversation Context。他们永远不能被绑定到无状态Context。
注意,在集群环境中,把Entity Bean直接绑定到Conversation或者Session范围的Seam上下文变量,与在有状态Session Bean中保持一个对Entity Bean的引用相比,性能比较差。因此,并非所有的Seam应用程序都会把Entity Bean定义为Seam组件。
Seam实体Bean组件可以使用 Component.getInstance()、@In(create=true) 或者直接使用 new 操作来实例化。
(4) JavaBeans
JavaBeans可以像无状态或者有状态Session Bean那样使用。但是,它们不能提供Session Bean那么多的功能(声明式事务划分、声明式安全性、高效的集群状态复制、EJB 3.0持久化、超时方法等等)。
在后面有一章,我们会展示如何在没有EJB容器的情况下使用Seam和Hibernate。此时,组件是JavaBeans,而非Session Beans。 但是注意,在很多应用服务器中,对Conversation或Session 范围的Seam JavaBean组件集群操作,要比对有状态Session Bean组件集群慢。
默认,JavaBeans是绑定到Event Context的。
对Session范围的JavaBeans的并发请求总是会被Seam转化为串行执行。
Seam JavaBean组件可以使用 Component.getInstance()、@In(create=true) 或者直接使用 new 操作来实例化。
(5)消息驱动Bean
消息驱动Bean通常作为Seam组件。但是,消息驱动Bean与其他Seam组件的调用方式非常不同——它们并非通过Context变量调用,它们会监听发送到JMS Queue或者Topic的消息。
消息驱动Bean不能被绑定到Seam上下文。它们也不能访问它们的“调用者”的Session或者会话状态。但是,它们支持双向注入和一些其他的Seam功能。
消息驱动Bean不会被应用实例化,它是在接受到一条消息时由EJB容器来完成实例化的。
(6) 拦截
为了表演Seam的魔术(双向注入,上下文划分,校验等),它必须对组件调用进行拦截。对JavaBean而言,Seam可以完全控制组件的初始化,不需要特别的配置。对于Entity Bean,也不需要拦截器,因为双向注入和上下文划分不起作用。 对Session Bean,我们必须为它注册EJB拦截器。我们可以使用注解,比如:
@Stateless
@Interceptors(SeamInterceptor.class)
public class LoginAction implements Login {
...
}
但是更好的办法是在 ejb-jar.xml 中定义拦截器。
<interceptors>
<interceptor>
<interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor>
</interceptors>
<assembly-descriptor>
<interceptor-binding>
<ejb-name>*</ejb-name>
<interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class>
</interceptor-binding>
</assembly-descriptor>
(7) 组件名字
所有Seam组件都需要名字。我们可以通过 @Name 注解来命名组件:
@Name("loginAction")
@Stateless
public class LoginAction implements Login {
...
}
这个名字是 seam component name,和EJB规范定义的任何其他名字都没有关系。 但是,Seam组件名字就相当于JSF管理的Bean Name的名字,因此,可以理解为这两个概念是等同的。
@Name 不是定义组件名称的唯一方式,但是我们总得要在 某个地方 来指定名字。 否则,Seam 所有的注解部分就无法工作。
就如同在JSF中,Seam组件实例绑定成上下文变量时,其名字通常和组件名相同。 因此,例如我们可以通过 Contexts.getStatelessContext().get("loginAction") 来访问 LoginAction。 特别是,不管Seam自己何时初始化一个组件,它将这个新实例以组件的名字绑定成一个变量。 但是,又和JSF一样,应用程序也可以把组件绑定成其他的上下文变量,只需通过API编程调用。 例如,当前登录的用户(User)可以被绑定成为Session上下文中的 currentUser 变量,而同时,另一个用作某种管理功能的用户则被绑定成对话上下文的 user 变量。
对非常大型的应用程序,经常使用全限定名;内置的Seam组件就是这样。
@Name("com.jboss.myapp.loginAction")
@Stateless
@Interceptors(SeamInterceptor.class)
public class LoginAction implements Login {
...
}
我们可以在Java代码和JSF表达式语言中使用全限定的组件名称。
<h:commandButton type="submit" value="Login"
action="#{com.jboss.myapp.loginAction.login}"/>
这很啰嗦,Seam也提供了把全限定名简写的办法。在 components.xml 文件中加入类似这样的一行:
<factory name="loginAction" scope="STATELESS" value="#{com.jboss.myapp.loginAction}"/>
所有的Seam内置组件都有全限定名,但大多数都在Seam jar文件的 components.xml 中简写为简单的名字。
(8) 定义组件范围(Defining the Component Scope)
我们可以使用 @Scope 注解来覆盖默认的组件范围(上下文)。这可以让我们定义组件实例被Seam初始化后绑定到的具体上下文。
@Name("user")
@Entity
@Scope(SESSION)
public class User {
...
}
org.jboss.seam.ScopeType定义了可能范围的枚举.
(9)具有多个角色的组件(Components with multiple roles)
有些Seam组件类可以在系统中具有多个角色。例如,我们经常有一个 User 类用作Session-Scoped组件,代表当前用户,同时它又在用户管理界面中被用作Conversation-Scoped组件。@Role 注解让我们可以定义组件在另一个范围中的额外角色名 —— 这可以让我们把相同的组件类绑定成不同的上下文变量。(任何Seam组件 实例 都可以被绑定到多个上下文变量,但@Role使得我们也可以在类的级别做到这一点,从而享受自动实例化的优点。)
@Name("user")
@Entity
@Scope(CONVERSATION)
@Role(name="currentUser", scope=SESSION)
public class User {
...
}
@Roles 注解可以让我们为组件指定任意多的附加角色。
@Name("user")
@Entity
@Scope(CONVERSATION)
@Roles({@Role(name="currentUser", scope=SESSION),
@Role(name="tempUser", scope=EVENT)})
public class User {
...
}
(10) 内置组件
和很多优秀的框架一样,Seam自产自用,主要实现了一系列的内置Seam拦截器(后文详述)和Seam组件。这让应用程序在运行时和内置的组件交互变得很容易,甚至可以用自己编写的实现来替换掉内置组件,由此来定制Seam的基本功能。内置组件在 org.jboss.seam.core 这个Seam 命名空间中定义,Java包名也是相同的。
像所有Seam组件一样,内置组件也可以被注射,但是它们也提供了便利的instance()静态方法:
FacesMessages.instance().add("Welcome back, #{user.name}!");
分享到:
相关推荐
压缩包中的文件"Seam-Carving-Matlab-master"可能包含以下组件: 1. `seam_carving.m`:主函数,实现整个Seam Carving流程。 2. `gradient.m`:计算图像梯度的辅助函数。 3. `energy_map.m`:根据梯度计算能量图的...
Seam - 语境相关的组件[满江红20071230]............................................................................................................................ 1 Java EE 框架...........................
文件"Seam - 语境相关的组件.pdf"很可能是Seam框架深入学习的教程或指南,涵盖了上述概念的详细解释和示例。通过阅读这份资料,你应该能掌握Seam框架如何利用语境相关的组件来优化Java EE应用的开发,以及如何在实际...
- **描述符的作用**:Seam 组件描述符是一种用于定义组件行为和特性的机制,它可以帮助开发者更高效地管理和配置组件。 - **注解支持**:Seam 组件描述符大量依赖于注解,使得组件的定义更加简洁直观。 5. **...
**JBoss Seam组件中文手册** **一、Seam框架概述** Seam是一个开源的企业级Java框架,由JBoss公司开发,旨在简化Java EE应用程序的开发。它将多种技术如JavaServer Faces (JSF),Java Persistence API (JPA),EJB 3...
2. **组件添加**:通过`seam component`命令,可以方便地将Seam组件添加到项目中,如EJB、JSF等。 3. **自动构建**:支持Maven集成,可以使用`seam build`进行项目的自动化构建。 4. **部署与运行**:`seam deploy`...
通过学习和理解Seam,开发者可以更有效地构建可扩展、可维护的Java EE应用,利用其强大的上下文相关组件模型和事件驱动架构,提高开发效率,减少代码的复杂性。无论是对于企业级应用开发还是个人项目,Seam都是一个...
- Seam 组件既可以是 POJO 也可以是 EJB。 - 支持依赖注入(DI)和反向依赖注入(BI)。 - 支持配置异常处理和注解。 - **会话范围**:会话范围是 Seam 的一个重要特性,它允许组件保持状态直到用户结束会话。 #...
- **作用**:更新项目中的依赖库,以确保项目使用的组件是最新的版本。 4. **`delete-project`** - **命令示例**:`seam.bat delete-project` - **作用**:删除指定的项目目录,并从JBoss服务器中取消部署该...
8. **Seam组件**:了解如Conversation、Transactions、邮件服务等Seam内置组件的使用方法。 9. **实时性与Ajax**:探索Seam如何实现实时更新和Ajax功能,提升用户体验。 ### Seam官方参考手册 Seam官方参考手册...
- **Seam组件**: - **无状态SessionBean**:执行短暂的任务。 - **有状态SessionBean**:保持状态,适用于长时间的操作。 - **实体Bean**:代表数据库中的实体。 - **JavaBeans**:简单的 Java 对象,用于封装...
接着,通过注册示例详细展示了Seam的基础结构,包括实体Bean(如User)、无状态和有状态会话Bean、Seam组件部署描述文件(components.xml)、Web部署描述文件(web.xml)、JSF配置、EJB部署描述文件、持久化部署描述...
此外,Seam还支持基于组件的事件传播,使得组件之间可以通过事件进行通信,增强了系统的可扩展性和灵活性。 **POJOs处理JSF事件** 在传统的JSF应用中,处理用户界面事件通常需要编写大量的Managed Beans。而在...
#### 四、Seam组件配置 ##### 配置方式 - **通过属性设置**: 在组件类中直接定义属性值。 - **通过components.xml文件**: 更灵活地配置组件行为,无需修改源代码。 - **细粒度配置文件**: 为特定组件或组件组提供...
- Seam3拆分了Seam2的功能,提供了一系列模块化的组件,如seam-solder、seam-config-xml、seam-servlet等。 3. JBoss Seam3环境要求: - 支持JbossAS6和JbossAS7.x应用服务器。 - 需要JDK1.5及以上版本支持。 -...
- 组件模型:Seam组件是可注入、可管理的对象,支持声明式依赖注入。 - 事件处理:Seam提供了一种强大的事件发布和订阅机制,允许组件之间通过事件进行通信。 - 集成性:与JSF、EJB、Hibernate等Java EE技术无缝集成...
- **打开Seam组件**:本部分解释了如何直接打开特定的Seam组件,这对于调试和维护工作非常有用。 #### 5. Seam向导 - **新建Seam Action**:Seam Actions是Seam框架的核心组成部分之一。这部分内容详细介绍了如何...
为了确保组件能够被正确识别与使用,每个Seam组件都必须拥有一个唯一的名称标识,即通过`@Name`来指定。例如: ```java @Name("componentName") public class ExampleComponent { // 组件实现细节 } ``` 这里的`...