Chapter 27. Seam注解 -seam满江红
编写Seam应用程序时需要使用大量的注解。Seam让我们使用注解获得声明式编程风格。大部分注解由EJB3.0规范定义。 数据验证通过Hibernate Validator包定义。最后,Seam定义了它自己的注解集合,这就是我们这一章将要描述的。
所有这些注解在 org.jboss.seam.annotations 包中定义。
我们要看的第一组注解让我们定义一个Seam组件。这些注解在组件(component)类中出现。
@Name("componentName")
为一个类定义一个Seam组件。所有Seam组件都需要该注解。
@Scope(ScopeType.CONVERSATION)
定义默认的组件上下文。可以定义的值由 ScopeType 枚举:EVENT, PAGE, CONVERSATION, SESSION, BUSINESS_PROCESS, APPLICATION, STATELESS。
当范围没有显式定义时,默认的范围取决于组件类型。 对于无状态会话bean,默认是 STATELESS。 对于Entity Bean和Stateful Session Bean,默认是 CONVERSATION。 对于JavaBean,默认是 EVENT。
@Role(name="roleName", scope=ScopeType.SESSION)
允许一个Seam组件绑定多个上下文变量。 @Name/@Scope 注解定义一个“默认角色”。每一个 @Role 注解定一个附加角色。
-
name — 上下文变量的名字。
-
scope — 上下文变量的作用域。当没有显式定义作用域时,和上面一样默认取决于组件类型。
@Roles({ @Role(name="user", scope=ScopeType.CONVERSATION), @Role(name="currentUser", scope=ScopeType.SESSION) })
允许指定多个额外角色。
@BypassInterceptors
取消在特定组件或者一个组件方法上的所有拦截器。
@JndiName("my/jndi/name")
Seam查找EJB组件的JNDI名。 如果没有显式指定JNDI名,Seam将使用由 org.jboss.seam.core.init.jndiPattern 指定的JNDI模式。
@Conversational
声明一个对话作用域组件是对话式的,亦即只有长期运行的对话处于活动状态时,组件中的方法才可以被调用。
@Scope(APPLICATION) @Startup(depends="org.jboss.seam.bpm.jbpm")
指定某个Application Scope的组件在初始化时立即启动。它主要用于特别的内置组件,用于引导象JNDI,数据源等等关键性的设施。
@Scope(SESSION) @Startup
指定某个Session Scope的组件在Session建立时立即启动。
-
depends — 依赖于,指定必须在此之前启动的命名组件(如果已安装)。
@Install(false)
指定组件是否应该被默认安装。没有@Install注解则表明该组件应该被安装。
@Install(dependencies="org.jboss.seam.bpm.jbpm")
如果所指定的依赖组件被安装,那么该组件才安装。
@Install(genericDependencies=ManagedQueueSender.class)
如果所指定的类的某个实现组件被安装,那么该组件才安装。当无法确定依赖组件的唯一公开名字时,这就有用了。
@Install(classDependencies="org.hibernate.Session")
如果所指定的类在classpath中,那么该组件才安装。
@Install(precedence=BUILT_IN)
指定组件的优先级别。如果具有相同名字的多个组件存在,具有高优先级的才被安装。定义的优先级是(递增排序):
-
BUILT_IN — 所有内置的Seam组件的优先级别
-
FRAMEWORK — 用于扩展Seam的框架组件的优先级别
-
APPLICATION — 应用程序的组件优先级别(默认优先级)
-
DEPLOYMENT — 在特定部署中重载应用程序组件的组件优先级别
-
MOCK — 在测试时mock对象使用的优先级别
@Synchronized(timeout=1000)
如果组件被多个客户端并发访问,Seam应该串行化请求。如果一个请求在给定时间段内没有得到组件的锁,将抛出一个例外。
@ReadOnly
声明JavaBean组件或者组件方法在调用结束时不要求状态复制。
@AutoCreate
声明组件将被自动建立,即使客户端不定义 create=true。
下面两个注解控制双向注入。这些属性用于组件实例变量或者属性访问方法中。
@In
在每次组件调用开始时,从上下文变量注入此组件属性。如果上下文变量是null,那么一个异常将被抛出。
@In(required=false)
在每次组件调用开始时,从上下文变量注入此组件属性。上下文变量可为null。
@In(create=true)
在每次组件调用开始时,从上下文变量注入此组件属性。如果上下文变量为null,那么Seam实例化这个组件。
@In(value="contextVariableName")
显式指定上下文变量的名字,而不再使用注解定义的实例变量名。
@In(value="#{customer.addresses['shipping']}")
在每次组件调用开始时,用一个JSF EL表达式的计算结果来注入组件属性。
-
value — 指定上下文变量名。默认是组件属性名。可选地,指定一个JSF EL表达式,放在 #{...} 符号中。
-
create — 指定若上下文变量名在所有上下文中均未定义,Seam应该创建一个组件作为上下文变量,名字即为所要求的名字。默认为false。
-
required — 指定若上下文变量名在所有上下文中均未定义,Seam应抛出异常。
@Out
在调用结束后注射出Seam组件属性到上下文变量。若属性为null,则抛出一个异常。
@Out(required=false)
在调用结束后注射出Seam组件属性到上下文变量。属性可以为null。
@Out(scope=ScopeType.SESSION)
在调用结束后注射出非Seam组件属性到指定scope。
或者,若没有明确指定scope,则使用此 @Out 属性所属组件的scope。(如果此组件是无状态的,则使用 EVENTscope 。)
@Out(value="contextVariableName")
显式指定上下文变量名,而非使用注解中指定的实例变量名。
-
value — 指定上下文变量名。默认为组件属性名。
-
required — 指定若注射出时组件属性为null,Seam应抛出异常。
注意一起使用这些注解相当常见,例如:
@In(create=true) @Out private User currentUser;
下一个注解支持 管理器组件(manager component) 模式,在该模式中一个Seam组件管理一些其他将被注入的class实例的生命周期。它在组件的getter方法中出现。
下一个注解支持 工厂组件(factory component) 模式,在该模式中,一个Seam组件负责初始化上下文变量值。 如果出现非faces的request,在渲染response的时候,它用于初始化所需要的状态特别有用。它出现在组件方法中。
@Factory("processInstance") public void createProcessInstance() { ... }
说明当上下文变量没有值时,此组件的方法被用来初始化上下文变量值。它用于返回值是 void 的方法。
@Factory("processInstance", scope=CONVERSATION) public ProcessInstance createProcessInstance() { ... }
声明方法返回一个值,当上下文变量没有值时Seam应使用此值初始化命名上下文变量值。它用于返回一个值的方法。 若没有指明scope,则使用 @Factory 方法所在组件的scope(除非组件是无状态的,则使用 EVENT 上下文)。
-
value — 指定上下文变量值。若为getter方法,默认为JavaBean属性名。
-
scope — 指定Seam应绑定返回值的作用域。仅针对于返回一个值的工厂方法有意义。
-
autoCreate — 无论什么时候请求变量,此工厂方法将自动被调用,即使@In未指定create=true。
下面的注解让你注入一个 日志(Log):
@Logger("categoryName")
使用 org.jboss.seam.log.Log 的实例注入一个组件字段。对于Entity Bean,该字段必须声明为static。
-
value — 指定日志category。默认是组件类名。
最后一个注解让你注入一个request参数值:
这些注解允许组件响应它自己的生命周期事件。它们作用于组件方法。对每个组件class来说,每种注解只允许出现一次。
@Create
当组件实例被Seam初始化时,该方法应被调用。注意仅有JavaBean和Stateful Session Bean支持create方法。
@Destroy
当上下文结束和它的上下文变量销毁时,该方法应被调用。注意仅有JavaBean和Stateful Session Bean支持destroy方法。
Destroy方法应仅仅用于清理工作。Seam 会捕捉、记录,然后消灭destroy方法传播的任何异常。
@Observer("somethingChanged")
指定当特定类型的component-driven(组件驱动)事件发生时,该方法应被调用。
@Observer(value="somethingChanged",create=false)
当指定类型的一个事件发生时,该方法应被调用,但若实例都不存在,则不创建实例。 若实例不存在并且create是false,事件将不会觉察到。create的默认值是true。
这些注解提供声明式对话分界(declarative conversation demarcation)。它们在Seam组件方法中使用,通常是动作监听器方法(Action Listener Method)。
每个Web请求有一个对话上下文和它关联。这些对话的大多数在请求结束时结束。如果你想要一个对话跨越多个请求,你必须通过调用标志为 @Begin 的方法来“提升”当然的对话为一个长期运行的对话(long-running conversation)。
@Begin
当此方法无异常的返回一个非空结果时,一个长期运行的对话开始。
@Begin(join=true)
若已经处于长期运行对话中,简单的延续此对话上下文。
@Begin(nested=true)
若已经处于长期运行对话中,一个新的被 嵌套(nested) 对话上下文开始。 该被嵌套的对话在遇到下一个 @End 时结束,并且外部上下文将恢复。在同一个外部对话中同时嵌套多个对话是完全合法的。
@Begin(pageflow="process definition name")
指定该对话的页面流(pageflow)的jBPM进程定义名。
@Begin(flushMode=FlushModeType.MANUAL)
指定任何Seam管理的持久上下文的flush模式。flushMode=FlushModeType.MANUAL 支持 原子对话(atomic conversations),这里所有写操作在会话上下文进入队列,直到显式调用 flush()(调用通常发生在对话结束时)。
-
join — 定义当长期对话已经存在时的行为。 若是true,传播上下文。若为 false,抛出一个异常。 默认为false。当指定 nested=true 时,将忽略该设置。
-
nested —当长期对话已经存在时,一个嵌套对话应该建立。
-
flushMode — 设置任何在此会话期间创建的,被Seam管理的Hibernate Session或JPA持久上下文的flush模式。
-
pageflow — 由 org.jboss.seam.bpm.jbpm.pageflowDefinitions 部署的一个jBPM处理的进程定义名。
@End
当这个方法无异常的返回一个非空输出时,长期对话结束。
-
beforeRedirect — 默认情况下,若有重定向,直到所有的重定向结束后,对话才会被真正destory。 设置beforeRedirect=true指定该对话应在当前request结束时就结束,并且在一个新的临时对话上下文中处理重定向。
@StartTask
"开始"一个jBPM任务。当此方法无异常的返回一个非空输出时,长期运行对话开始。此对话同在某个request具名参数中被指定的jBMP任务相关联。 在该会话上下文中,还定义了一个业务流程上下文(business process context),用作任务实例的业务流程实例。
jBPM的 TaskInstance 在request context中以 taskInstance 的名字作为变量出现。 jPBM的 ProcessInstance 在request context中以 processInstance 的名字作为变量出现。(当然,这些对象也可用于通过 @In 注入。)
-
taskIdParameter — 保存有task id的request参数的名字。 默认为"taskId",同时也是Seam taskList JSF component使用的默认值。
-
flushMode — 设置任何在此对话期间创建的,被Seam管理的Hibernate Session或JPA持久上下文的flush模式。
@BeginTask
恢复一个未完成的jBMP任务。当此方法无异常的返回一个非空值时,长时间运行的对话开始。此对话同在某个request参数中指定的jBMP任务相关联。 在该对话上下文中,还定义了一个业务流程上下文(business process context),用作任务实例的业务流程实例。
jBPM的 org.jbpm.taskmgmt.exe.TaskInstance 在request context中以 taskInstance 的名字作为变量出现。 jBPM的 org.jbpm.graph.exe.ProcessInstance 在request context中以 processInstance 的名字作为变量出现。
-
taskIdParameter — 保存有task id的request参数的名字。 默认为"taskId",同时也是Seam taskList JSF component使用的默认值。
-
flushMode — 设置任何在此会话期间创建的,被Seam管理的Hibernate Session或JPA持久上下文的flush模式。
@EndTask
"结束"一个jBPM任务。当此方法无异常返回一个非空输出时,结束长时间运行的会话。触发一个jBMP 流转(transition)。 若没有调用 transition 内置组件的 Transition.setName() 方法,实际被触发的将是默认的transition。
@EndTask(transition="transitionName")
触发给定jBPM流转。
-
transition — 当任务结束时触发的jBPM流转名。默认为默认的流转transition。
-
beforeRedirect — 默认情况下,若有重定向,直到所有的重定向结束后,会话才会被真正destory。 设置 beforeRedirect=true 指定该会话应在当前request结束时就结束,并且在一个新的临时会话上下文中处理重定向。
@CreateProcess(definition="process definition name")
当方法无异常返回一个非空输出时,建立一个新的jBPM流程实例。 ProcessInstance 对象在上下文中以 processInstance 的名字作为一个变量出现。
-
definition — 通过 org.jboss.seam.bpm.jbpm.processDefinitions 部署的jBPM 流程定义的名字。
@ResumeProcess(processIdParameter="processId")
当方法无异常返回一个非空输出时,重新进入一个已存的jBPM 流程实例的context。ProcessInstance 对象在上下文中以 processInstance 的名字作为一个变量出现。
-
processIdParameter — 保存有该流程id的request参数名。默认是 "processId".
@Transition("cancel")
当此方法返回一个非空结果时,向在当前jBPM流程实例中发送一个流转信号。
Seam提供一个注解,来让你根据某个动作监听器的输出强制回滚JTA事务。
@Transactional
声明JavaBean组件具有与Session Bean组件默认事务行为类似的行为。 也就是说,方法调用应该发生在一个事务中,如果当调用方法时没有事务存在,一个事务将特地为该方法启动。此注解可以在类或者方法级应用。 不要把此注解用于EJB3.0组件,那时候应该用 @TransactionAttribute!
@Transactional
TDB
@Transactional
TDB
这些注解大多用在JavaBean Seam组件中。若你用EJB3.0组件,你应改采用标准的 @TransactionAttribute 注解。
这些注解让你指定Seam应如何处理一个从Seam组件中传播出来的异常。
@Redirect(viewId="error.jsp")
声明被注解的异常引起浏览器重定向到特定视图id。
-
viewId — 指定重定向到的JSF视图id。你可以在这里使用EL。
-
message — 指定显示的信息,默认是异常信息。
-
end — 指明是否终止长时间运行的对话,默认为 false。
@HttpError(errorCode=404)
声明被注解的异常导致发送一个HTTP错误。
-
errorCode — HTTP错误码,默认为500。
-
message — 和HTTP错误一起被发送的信息,默认为异常消息。
-
end — 指明是否终止长时间运行的对话,默认为 false。
Seam Remoting要求会话Bean的本地接口要采用以下的注解:
以下注解出现在Seam拦截器类中。
请查阅EJB3.0规范文档获得EJB拦截器定义所要求的注解的信息。
@Interceptor(stateless=true)
指定这个拦截器是无状态的,Seam可以优化复制。
@Interceptor(type=CLIENT)
指定次拦截器是一个“客户端”拦截器,在EJB容器之前调用它。
@Interceptor(around={SomeInterceptor.class, OtherInterceptor.class})
指定此拦截器在栈中的位置比给定的拦截器更高。
@Interceptor(within={SomeInterceptor.class, OtherInterceptor.class})
指定此拦截器在栈中的位置比给定的拦截器更深。
以下注解用于声明一个异步方法,例如:
@Asynchronous public void scheduleAlert(Alert alert, @Expiration Date date) { ... }
@Asynchronous public Timer scheduleAlerts(Alert alert, @Expiration Date date, @IntervalDuration long interval) { ... }
以下注解让使用JSF变得更容易。
允许一个Seam组件作为JSF转换器(JSF converter)。 被注解类必须是一个Seam组件,必须实现javax.faces.convert.Converter接口。
-
id — JSF转换器id。默认为组件名。
-
forClass — 若被指定,注册该组件为一个类型的默认转化器。
允许一个Seam组件作为JSF验证器(JSF Validator)。 被注解类必须是一个Seam组件,必须实现 javax.faces.validator.Validator 接口。
-
id — JSF验证器id。默认为组件名。
以下注解让用Stateful Session Bean作为后台实现可点击列表更容易。它们在属性成员(attributes)上使用。
@DataModel("variableName")
将一个类型为 List、Map、Set 或 Object[] 的属性作为一个JSF DataModel 置入所属组件的scope(如果所属组件是 STATELESS则为EVENT scope )。 当它是 Map 时,DataModel 的每一行是一个 Map.Entry。
-
value — 转换器上下文参数名。默认是属性名。
-
scope — 若scope=ScopeType.PAGE 显式指定,则 DataModel 将在 PAGE 上下文作用域内。
@DataModelSelection
从JSF DataModel(这是基本集合或者映射值的一个元素)注入一个选定值。 如果组件只定义一个 @DataModel 属性,那么 DataModel 所选中的值将被注入。 否则,每个 @DataModel 组件名称必须被指定到每个 @DataModelSelection 的值属性中。
如果在所关联的 @DataModel 上声明了 PAGE scope,除了注入的DataModel Selection,所关联的DataModel也会被注入。 此时,如果标注有 @DataModel 注解的属性是getter方法,该Seam组件必须有同名的setter方法作为Business API的一部分。
-
value — 对话上下文参数名。若在组件中有一个明确的 @DataModel,则不需要该属性。
@DataModelSelectionIndex
暴露JSF DataModel 的选择索引作为一个组件属性(这是底层集合的行号,或者map key)。 如果组件只定义一个 @DataModel 属性,那么 DataModel 所选中的值将被注入。 否则,每个 @DataModel 组件名称必须被指定到每个 @DataModelSelection 的值属性中。
-
value — 对话上下文参数名。若在组件中有一个明确的 @DataModel 则不需要该属性。
这些元数据注解使得list以外的其它数据结构实现类似 @DataModel 和 @DataModelSelection 的功能成为可能。
这个注解提供一个为声明关于一系列要打包在一起的组件信息的机制。它能应用于任何Java包。
@Namespace(value="http://jboss.com/products/seam/example/seampay")
指定目前包中的组件关联到给定命名空间。为了简化应用配置,声明的命名空间可以在 components.xml 文件中作为XML命名空间来使用。
@Namespace(value="http://jboss.com/products/seam/core", prefix="org.jboss.seam.core")
指定一个关联到给定包的命名空间。另外,它指定一个组件名前缀,用于XML文件中出现的组件名。 例如,一个和该命名空间关联的叫 init 的XML元素可被理解为实际引用一个叫做 org.jboss.seam.core.init 的组件。
这些注解允许你将你的Seam组件和Servlet容器集成。
使一个用 @Filter 注解的Seam组件(它实现了 javax.servlet.Filter 接口)作为一个Servlet 过滤器(Filter)使用。它将会被Seam的主Filter执行。
-
@Filter(around={"seamComponent", "otherSeamComponent"})
指定此过滤器的在栈中的位置比指定过滤器更高。
-
@Filter(within={"seamComponent", "otherSeamComponent"})
指定此过滤器在栈中的位置比既定的过滤器更深。
相关推荐
**JSF、Seam与JPA整合实例详解** 在现代Web应用开发中,JavaServer Faces (JSF)、Seam框架和Java Persistence API (JPA)是三个关键的技术组件。本实例将深入探讨如何利用这三者进行联合开发,帮助开发者实现高效、...
Seam 是一个强大的Java EE框架,它主要用于简化JavaServer Faces (JSF)应用程序的开发,同时提供了对EJB 3、CDI(Contexts and Dependency Injection)、Ajax等技术的集成。在JSF项目中配置Seam,可以充分利用其优势...
1. **集成JSF和EJB 3.0**:Seam允许开发者将EJB 3.0的业务组件直接与JSF页面进行交互,通过注解方式消除两者之间的接口障碍,减少了手动创建facade对象的需求。 2. **注解驱动的配置**:Seam采用JDK 5.0的注解技术...
**JSF、Seam与Hibernate简介** JSF(JavaServer Faces)是Java平台上的一个用于构建用户界面的组件模型框架,它提供了一种声明式的方式来创建动态Web应用程序。JSF的核心概念是组件,这些组件可以组合成用户界面,...
例如,Seam可以自动管理Hibernate的Session,提供事务控制,以及实现基于注解的实体管理和查询。 JavaServer Faces (JSF) 是一种用于构建Web用户界面的MVC(模型-视图-控制器)框架。JSF组件库强大,可帮助开发者...
### Seam-无缝集成JSF #### 一、概述 Seam作为一个强大的应用程序框架,旨在扩展JSF(JavaServer Faces)的功能,为Java Web应用程序开发者提供更完善的解决方案。JSF作为Java Web应用程序的标准框架之一,虽然...
Seam是一个Java EE框架,它将JavaServer Faces(JSF)、Java Persistence API(JPA)、Inversion of Control(IoC)和Enterprise JavaBeans(EJB)等技术融合在一起,为开发复杂的Web应用程序提供了便利。在Seam框架...
Seam项目源代码是一个基于JBoss应用服务器、JavaServer Faces (JSF)、Enterprise JavaBeans (EJB3) 的开源框架示例,旨在为初学者提供深入理解这些技术结合使用的实践经验。Seam是一个全面的Java EE开发框架,它简化...
Seam 是一个开源的Java框架,它主要用于简化企业级应用的开发,特别是在JavaServer Faces (JSF) 和Java Persistence API (JPA) 上的工作。Seam 提供了一种集成的解决方案,将各种Java EE组件(如JSF、EJB、CDI等)...
Seam - 语境相关的组件[满江红20071230]............................................................................................................................ 1 Java EE 框架...........................
Seam与JSF的结合,通过Seam组件,可以轻松处理复杂的数据绑定和事件处理,提高了UI开发的效率。 Seam中的EJB支持则允许开发者利用Enterprise JavaBeans进行业务逻辑处理。Seam简化了EJB的使用,不需要繁琐的接口和...
Seam是一个开源的Java EE框架,它将JavaServer Faces(JSF)与EJB3、Hibernate等技术结合在一起,提供了一种更为简化的企业级开发方式。在这个“seam级联菜单例子”中,我们将深入探讨如何在Seam应用中实现级联选择...
它通过整合JSF(JavaServer Faces)与EJB 3.0(Enterprise JavaBeans 3.0)组件,并充分利用JDK 5.0中的注解技术,为开发人员提供了构建复杂Web应用的新模式。Seam旨在简化企业级应用的开发过程,同时提高应用的可...
Seam还提供了一套增强JSF的工具,包括JSF组件标签和注解,这些工具增强了JSF的“Web友好性”和网页效率。例如,Seam解决了JSF中常见的问题,即对HTTP POST的过度依赖,这让通过HTTP GET访问JSF页面变得非常困难。...
### jboss-seam 注解详解 #### @Name 在JBoss Seam框架中,`@Name`注解主要用于定义一个Seam组件。为了确保组件能够被正确识别与使用,每个Seam组件都必须拥有一个唯一的名称标识,即通过`@Name`来指定。例如: `...
Seam的核心理念是将不同的技术,如JavaServer Faces (JSF)、Java Persistence API (JPA)、Enterprise JavaBeans (EJB)以及Java Message Service (JMS),无缝融合在一起,创建一个统一的开发环境。 在"Seam - 语境...
这个经典教程结合了Seam、EJB 3.0和JSF(JavaServer Faces)的使用,旨在帮助开发者深入理解这三个技术的集成和交互,以及如何在实际项目中应用它们。 EJB 3.0是Enterprise JavaBeans的第三个主要版本,它极大地...