Seam是一种企业级Java的应用程序框架。它的灵感源自下列原则:
Seam为你的应用程序中所有的业务逻辑定义了一种统一的组件模型。 Seam组件可能是有状态的,包含与几个定义良好的上下文中任何一个相关联的状态, 包括长时间运行上下文、持久化上下文、业务流程上下文, 以及用户交互中能够跨多个Web请求保存的对话上下文。
Seam中的表现层组件和业务逻辑组件之间并没有区别。 你可以根据你设计的任何架构给应用程序进行分层,而不是强制将你的应用程序逻辑硬塞进一个由你目前在使用的任何框架组合所强加给你的不适当的分层配置中。
与简单的Java EE或者J2EE组件不同,Seam组件可以同时访问与Web请求相关的状态,以及保存在事务资源中的状态(而不必通过方法参数手工传播Web请求状态)。 你可能反对说由旧式的J2EE平台强加给你的应用程序分层是件好东西,没有什么可以阻止你利用Seam创建一个相当的分层架构— 区别在于,你要自己架构应用程序,并决定有哪些层,以及它们是如何合作的。
JSF和EJB 3.0是Java EE5的两个最好的新特性。EJB3是服务器端业务和持久逻辑的全新组件模型。 同时,JSF也是表现层的一个优秀组件模型。不幸的是,这二者都无法独自解决所有的计算问题。 实际上,JSF和EJB3结合使用后运作得最好。 但是Java EE5规范并没有提供如何整合这两个组件模型的标准方法。 所幸,这两种模型的创建者都前瞻到了这种状况,并且提供了标准的扩展点,允许对各自进行扩展,或者与其他解决方案集成。
Seam将JSF和EJB3的组件模型合二为一,消除了胶合代码,使得开发者专注于业务问题。
编写“一切”都是EJB的Seam应用程序是有可能的。如果你习惯把EJB当作是细粒度的所谓“重量化”的对象,这可能会令你很吃惊。 然而,从开发人员的角度来看,3.0版本已经完全改变了EJB的本质。 EJB是一个细粒度的对象—没有什么东西会比注解的JavaBean更复杂了。Seam甚至鼓励你使用会话Bean作为JSF动作监听者!
另一方面,如果你宁可不在这个时候采用EJB 3.0,不用勉强。 事实上,任何Java类都可以是一个Seam组件,并且Seam提供了你期待从“轻量化”的容器,甚至任何组件、EJB或者其他东西中获得的所有功能。
Seam支持两个最好的、开源的基于JSF的AJAX解决方案:JBoss RichFaces和ICEfaces。 这两个解决方案让你无需编写任何JavaSctipt代码就可以为你的界面添加AJAX功能。
Seam也提供了内置的JavaSctipt远程访问层,它让你异步地从客户端JavaScript中调用组件,而不需要中间的action层。 你还可以订阅服务器端的JMS主题,并通过AJAX的push方法接收信息。
假若不是有Seam内置的并发和状态管理能力,以上这些方法将都无法很好地运作。 这两种方法确保服务器端能够安全而高效地处理多个并发细粒度的异步AJAX请求。
Seam可以选择通过jBPM提供透明的业务流程管理。使用jBPM和Seam共同实现复杂的工作流、合作和任务管理,简单到了让人难以置信的程度。
Seam甚至允许你利用与jBPM给业务流程定义所使用的相同语言(jPDL)来定义表现层页面流。
JSF为表示层提供了非常丰富的事件模型。 通过以完全相同的事件处理机制暴露与jBPM业务流程相关的事件,Seam强化了这一模型,这就为Seam的统一组件模型提供了统一的事件模型。
从EJB早期开始,我们已经习惯于声明式事务管理和J2EE声明式安全的概念。EJB 3.0还引入了声明式持久上下文管理。 一个更广泛的管理状态问题--管理与某个特殊context关联的状态,有三个特例,它确保这个上下文结束时进行所有必要的清理。 Seam把声明式状态管理的概念推进的远得多,并把它应用于应用程序状态(application state)。 J2EE应用程序一般通过手工实现状态管理,通过获取和设置Servlet Session和Request属性。 假若程序没能清除Session属性,或者在多窗口的应用程序中,与不同的工作流关联的Session数据发生冲突,这种状态管理的方法就会成为很多Bug和内存泄漏的根源。 Seam有可能几乎完全消除这类Bug。
声明式应用程序状态管理通过Seam定义的丰富的context model(上下文模型)而成为可能。 Seam扩展了Servlet规范—定义的上下文模型——请求、会话、应用程序—增加了两个新的上下文— 对话和业务流程—,从业务逻辑的角度来看它们更具意义。
一旦你开始使用对话,将会惊讶于许多事情变得更加容易了。你曾经在像Hibernate或者JPA这样的ORM解决方案中痛苦地处理过延迟的关联抓取吗? Seam对话范围的持久化上下文意味着你将几乎看不到 LazyInitializationException。 你曾经遇到过刷新(Refresh)按钮或者后退(Back)按钮的问题吗?或者有过重复提交表单的问题吗? 有通过post-then-redirect传播信息的问题吗?Seam的对话管理解决了这些问题,甚至无需你真正去关注它们。 它们都是自Web最早期以来普遍的不良状态管理架构的征兆。
Inversion of Control(控制反转) 或者 dependency injection(依赖注入) 的概念出现在JSF和EJB3以及很多所谓的“轻型容器”中。 这类容器大多注重于实现 stateless services(无状态服务) 的组件注射。 即便在支持对有状态的组件进行注射的情况下(例如JSF),事实上也难以用于处理应用程序状态, 因为有状态组件的范围难以有效而灵活地定义,并且属于更广范围的组件不能被注入到属于更窄范围的组件中。
Bijection(双向注入)和IoC的不同之处在于它是动态的、语境相关的以及双向的。 你可以把这一机制理解成将语境相关的变量(与当前线程绑定的各种上下文中的名称)对应到组件的属性中。 双向注入允许由容器对有状态的组件进行自动组装。它甚至允许组件可以安全而简单地处理上下文变量的值,只需要把它赋给组件的属性。
Seam应用程序让用户自由地在多个浏览器窗口中切换,每个窗口都与一个不同的、安全隔离的对话关联。 应用程序甚至可以利用 workspace management,允许用户在一个浏览器窗口的多个对话(工作区)之间进行切换。 Seam不仅提供正确的多窗口操作,还提供在一个窗口中模拟多个窗口的操作。
传统上,关于到底哪些元信息可以算作配置,Java社区一直处于一种极为混乱的状态。 J2EE和流行的“轻型”容器为真正可以在不同的系统部署之间配置的东西,以及任何不容易用Java表达的其他声明都提供了基于XML的部署描述符。 Java 5 注解改变了所有这一切。
EJB3.0 接受注解和“对例外配置”,这成了以声明的形式为容器提供信息的最简易方法。不幸的是,JSF仍然在十分依赖笨重的XML配置文件。 Seam扩展了EJB 3.0 提供的注解,以用于声明式状态管理和声明式上下文划分。 这让你摆脱了对繁琐的JSF managed bean(JSF受管bean)的配置,减少了所需的XML,只剩下那些真正属于XML的信息(JSF导航规则)。
Seam组件作为POJO,天生就是可以进行单元测试的。但是对于复杂的应用程序,只有单元测试则还不够。 对于Java Web应用程序来说,集成测试一般是一项笨拙且困难的任务。因此,Seam为Seam应用程序提供了可测试性作为该框架的一项核心功能。 你可以轻易地编写重现与用户完整交互的JUnit或TestNG测试,来演习除了视图View(JSP或者Facelets页面)之外的所有系统组件。 你可以直接从你的IDE中运行这些测试,Seam会在那里自动地利用JBoss Embeddable部署EJB组件。
我们认为最新的Java EE规范很不错。但是我们知道它还远不够完美。 在规范中有许多漏洞(例如,GET请求的JSF生命周期中的局限性),Seam修正了这些漏洞。 Seam的创建者们正与JCP专家组一道,确保这些修正恢复到标准的下一次修订中。
当今的Web框架认为太小了。它们让你叫用户输入表单,并进入到你的Java对象。然后它们就让你悬着。 真正完整的Web应用程序框架应该解决像持久化、并发、异步、状态管理、安全、电子邮件、信息、PDF和图表生成、工作流、wikitext渲染、Web Services、缓存等等更多的问题。 一旦你尝到了Seam的甜头,就会惊讶地发现许多问题都变得更加简单了......
Seam为持久化集成了JPA和Hibernate 3,为轻量化的异步性集成了EJB Timer Service和Quartz,为工作流集成了jBPM,为业务规则集成了JBoss规则,为电子邮件集成了Meldware Mail,为完整的文本搜索集成了Hibernate Search和Lucene,为消息集成了JMS,以及为页面片断捕捉集成了JBoss Cache。 Seam在JAAS和JBoss规则之上,创建了一个新的基于规则的安全框架。甚至有用来渲染PDF、在线电子邮件和图表及wikitext的JSF标签库。 Seam组件可以同时作为一个Web Service进行调用,异步地从客户端JavaScript或者Google Web Toolkit,或者当然也可以直接从JSF调用。
Seam在任何Java EE应用程序服务器中都可以运行,甚至在Tomcat中也可以。如果你的环境支持EJB 3.0,好极了! 如果不支持,也没关系,你可以使用Seam为持久化内置的包含JPA或者Hibernate3的事务管理。 或者,你可以在Tomcat中部署JBoss Embedded,同时享有对EJB 3.0 的完整支持。
最终你会发现,Seam、JSF和EJB3的组合就是用Java编写复杂Web应用程序的 最 简单办法。你不会相信所需的代码是多么地少!
本文档翻译由俞黎敏作为Leader组织。翻译及一审、二审名单见下。王琳、马越对全书进行了三审。俞黎敏进行了全书统稿及发布的build工作。
Table 1. 翻译及审核人员列表
章节 | KB | 页数 | 翻译 | 一审 | 二审 |
---|---|---|---|---|---|
master.xml | 17K | CaoXiaogang | Echo | YuLimin | |
1. tutorial.xml (1.1-1.4) | 130K | 20P | seanchan | Jacky | DigitalSonic |
(1.5-1.11) | 24P | DigitalSonic | Jacky | ronghao | |
2. gettingstarted.xml | 21K | 6P | seanchan | zaya | DigitalSonic |
3. concepts.xml | 56K | 16P | CaoXiaogang | kuuyee | ronghao |
4. xml.xml | 25K | 7P | downpour | Echo | YuLimin |
5. events.xml | 39K | 11P | mochow | xihuyu2000 | Echo |
6. conversations.xml | 34K | 10P | magice | Echo | YuLimin |
7. jbpm.xml | 32K | 10P | 差沙 | ronghao | Echo |
8. persistence.xml | 23K | 6P | pesome | caoer | DigitalSonic |
9. validation.xml | 9K | 4P | pesome | DigitalSonic | YuLimin |
10. groovy.xml | 11K | 4P | kuuyee | DigitalSonic | YuLimin |
11. framework.xml | 20K | 7P | alexchang | CaoXiaogang | YuLimin |
12. drools.xml | 7K | 3P | DigitalSonic | shaozhou | Echo |
13. security.xml | 51K | 14P | YuLimin | xihuyu2000 | Echo |
14. i18n.xml | 14K | 4P | YY | DigitalSonic | Echo |
15. text.xml | 7K | 3P | DigitalSonic | yeshucheng(万国辉) | Echo |
16. itext.xml | 51K | 11P | lyfcdy | Echo | YuLimin |
17. mail.xml | 26K | 7P | chentianyi | yeshucheng(万国辉) | Echo |
18. jms.xml | 11K | 5P | YuLimin | caoer | Echo |
19. cache.xml | 11K | 3P | crazycy | CaoXiaogang | DigitalSonic |
20. webservices.xml | 9K | 3P | Echo | YuLimin | Echo |
21. remoting.xml | 37K | 13P | crazycy | agile_boy | Echo |
22. gwt.xml | 10K | 4P | yeshucheng(万国辉) | Echo | YuLimin |
23. spring.xml | 13K | 4P | YY | caoer | DigitalSonic |
24. hsearch.xml | 7K | 3P | yeshucheng(万国辉) | agile_boy | Echo |
25. configuration.xml | 48K | 15P | yeby | kuuyee | Echo |
26. annotations.xml | 64K | 14P | caoer | CaoXiaogang | YuLimin |
27. components.xml | 68K | 11P | jiaochar | zaya | HuYan |
28. controls.xml | 47K | 13P | Echo | YuLimin | Catherine |
29. elenhancements.xml | 5K | 2P | CaoXiaogang | yeshucheng(万国辉) | Echo |
30. testing.xml | 10K | 6P | agile_boy | CaoXiaogang | YuLimin |
31. tools.xml | 23K | 9P | junjzheng | CaoXiaogang | Echo |
32. oc4j.xml | 31K | 8P | yeshucheng(万国辉) | YuLimin | Echo |
33. dependencies.xml | 26K | 5P | yeshucheng(万国辉) | DigitalSonic | YuLimin |