jboss seam_JBoss Seam简介

jboss seam

本文是Michael Yuan和Thomas Heute即将出版的《 JBoss Seam:超越Java EE 5.0强大功能和灵活性》一书的第一章和第二章的摘录。

什么是缝?

JBoss Seam是“用于Java EE 5.0的轻量级框架”。 那是什么意思? Java EE(企业版)5.0本身不是“框架”的集合吗? 为什么您需要另一个超出官方规格的产品? 好吧,我们将Seam视为应该包含在Java EE 5.0中的“缺失框架”。 它位于Java EE 5.0框架之上,可为企业Web应用程序中的所有组件提供一致且易于理解的编程模型。 这也使轻而易举地开发了有状态应用程序和业务流程驱动的应用程序。 换句话说,Seam完全与开发人员的生产力和应用程序可伸缩性有关。

1.集成和增强Java EE框架

Java EE 5.0中的核心框架是EJB(企业JavaBeans)3.0和JSF(JavaServer Faces)1.2。 EJB 3.0(以下称为EJB3)是一个基于POJO(普通Java对象)的轻量级框架,用于业务服务和数据库持久性。 JSF是用于Web应用程序的MVC(模型-视图-控制器)组件框架。 大多数Java EE 5.0 Web应用程序都将具有用于业务逻辑的EJB3模块和用于Web前端的JSF模块。 但是,尽管EJB3和JSF相互补充,但它们被设计为独立的框架,各自具有自己的理念。 例如,EJB3使用批注来配置服务,而JSF使用XML文件。 此外,EJB3和JSF组件在框架级别上并不相互了解。 为了使EJB3和JSF协同工作,您需要人为的外观对象(即JSF支持bean)将业务组件绑定到网页,并需要样板代码(也称为管道代码)来跨越框架边界进行方法调用。 将这些技术融合在一起是Seam的职责之一。

Seam破坏了EJB3和JSF之间的人工层。 它提供了一种一致的,基于注释的方法来集成EJB3和JSF。 通过一些简单的注释,Seam中的EJB3业务组件现在可以直接用于支持JSF Web表单或处理Web UI事件。 Seam允许开发人员对所有应用程序组件使用“相同的东西”,即带注释的POJO。 与在其他Web框架中开发的应用程序相比,Seam应用程序在概念上很简单,并且相同功能所需的代码(Java和XML)少得多。 如果您不耐烦并且想要快速预览一下Seam应用程序的简单性,可以看看本文下面介绍的hello world示例。

Seam还使完成JSF上“困难”的任务变得容易。 例如,JSF的主要抱怨之一是它过于依赖HTTP POST。 很难为JSF网页添加书签,然后通过HTTP GET获取它。 好吧,使用Seam,生成可添加书签的RESTful网页非常容易。 Seam提供了许多JSF组件标签和注释,这些标签和注释可以提高JSF应用程序的“网络友好性”和网页效率。

同时,Seam将EJB3组件模型扩展到POJO,并将有状态上下文从Web层引入到业务组件。 此外,Seam集成了许多领先的其他开源框架,例如jBPM,JBoss Rules(又名Drools),JBoss Portal,JBoss Microcontainer等。Seam不仅“将它们连接在一起”,而且以与开发者类似的方式增强了框架。 JSF + EJB3组合。

虽然Seam植根于Java EE 5.0,但其应用程序并不限于Java EE 5.0服务器。 您的Seam应用程序可以部署在J2EE 1.4应用程序服务器以及普通Tomcat服务器中。 这意味着您可以立即获得Seam应用程序的生产支持!

1 + 1> 2

认为Seam只是将各种框架连接在一起的另一个集成框架是错误的。 Seam提供了自己的托管状态上下文,该上下文上下文允许框架通过注释,EL(表达语言)表达式等与其他框架进行深度集成。这种集成水平来自于Seam开发人员对第三方框架的深入了解。

2.理解ORM的Web框架

对象关系映射(ORM)解决方案已在当今的企业应用程序中广泛使用。 但是,当前大多数业务和Web框架都不是为ORM设计的。 他们不管理从请求进入到响应完全呈现的整个Web交互生命周期中的持久性上下文。 这导致了各种ORM错误,包括令人恐惧的LazyInitializationException ,并引起了诸如“数据传输对象”(DTO)之类的丑陋骇客。

Seam由世界上最流行的ORM解决方案(Hibernate)的发明者Gavin King发明。 它是专为促进ORM最佳实践而设计的。 使用Seam,不再需要编写DTO。 延迟加载才有效; 由于扩展的持久性上下文充当了减少数据库往返次数的自然缓存,因此可以大大提高ORM性能。

此外,由于Seam将ORM层与业务和表示层集成在一起,我们可以直接显示ORM对象,甚至可以在输入表单上使用数据库验证器注释,并将ORM异常重定向到自定义错误页面。

3.专为有状态Web应用程序而设计

Seam专为有状态的Web应用程序而设计。 Web应用程序本质上是多用户应用程序,而电子商务应用程序本质上是有状态的和可交易的。 但是,大多数现有的Web应用程序框架都面向无状态应用程序。 您必须摆弄HTTP会话对象来管理用户状态。 这不仅会使您的应用程序混乱不堪与核心业务逻辑无关的代码,而且会带来一系列性能问题。

在Seam中,所有基本应用程序组件本质上都是有状态的。 它们的状态由Seam声明式管理,因此比HTTP会话更易于使用。 无需在Seam应用程序中编写分散注意力的状态管理代码-只需使用组件的范围,生命周期方法和其他有状态属性对其进行注释-其余的工作就由Seam接管。 与纯HTTP会话相比,Seam有状态组件还对用户状态提供了更好的控制。 例如,您可以在HTTP会话中进行多个“对话”,每个对话由一系列Web请求和业务方法调用组成。

此外,数据库缓存和事务可以自动与Seam中的应用程序状态绑定在一起。 Seam自动将数据库更新保存在内存中,并且仅在对话结束时提交到数据库。 内存中的缓存大大减少了复杂的有状态应用程序中的数据库负载。

除了上述所有功能外,Seam还通过支持与开源JBoss jBPM业务流程引擎的集成,将Web应用程序中的状态管理向前迈进了一大步。 现在,您可以指定组织中不同人员(即客户,经理,技术支持等)的工作流程,并使用该工作流程来驱动应用程序,而不是依赖于UI事件处理程序和数据库。

4.支援Web 2.0

Seam已针对Web 2.0样式的应用程序进行了完全优化。 它提供了多种方式来支持AJAX(异步JavaScript和XML,一种向网页添加交互性的技术)支持-从无JavaScript的AJAX组件,支持AJAX的现有JSF组件到提供直接访问权限的自定义JavaScript库从浏览器到Seam服务器组件作为Javascript对象。 在内部,Seam提供了高级并发模型,以有效地管理来自同一用户的多个AJAX请求。

AJAX应用程序的一大挑战是数据库负载增加。 与非AJAX应用程序相比,AJAX应用程序向服务器发出的请求频率更高。 如果数据库必须满足所有这些AJAX请求,则数据库将无法处理负载。 Seam中的有状态持久性上下文充当内存中的缓存。 它可以在长时间运行的对话中保存信息,因此有助于减少数据库往返。

Web 2.0应用程序还倾向于为其数据采用复杂的关系模型(例如,社交网站只与管理和呈现“用户”之间的关系有关)。 对于这些站点,ORM层中的延迟加载至关重要。 否则,单个查询可能会级联以加载整个数据库。 正如我们前面所讨论的,Seam是当今唯一一个可以为Web应用程序正确支持延迟加载的Web框架。

5.通过依赖关系双射的POJO服务

Seam是“轻量级框架”,因为它促进了POJO(普通的旧Java对象)作为服务组件的使用。 没有框架接口或抽象类可将组件“挂钩”到应用程序中。 当然,问题是这些POJO如何相互交互以形成应用程序? 它们如何与容器服务(例如数据库持久性服务)交互?

接缝使用一种流行的设计模式(称为“依赖注入”(DI))将POJO组件连接在一起。 在这种模式下,Seam框架管理着所有组件的生命周期。 当一个组件需要使用另一个组件时,它将使用批注向Seam声明此依赖关系。 Seam根据应用程序的当前状态确定从何处获取此依赖组件,并将其“注入”到请求组件中。

在依赖注入概念的扩展上,Seam组件A还可以创建另一个组件B,并将创建的组件B“注入” Seam,以供其他组件(例如C)使用,以供以后使用。

这种双向依赖关系管理甚至在最简单的Seam Web应用程序中也得到了广泛使用(例如,第2章中的hello world示例)。 用Seam的术语来说,我们称其为“依赖性双射”。

6.例外配置

使Seam如此易于使用的关键设计原则是“异常配置”。 想法是为组件提供一组常识性的默认行为。 当所需的行为不是默认行为时,开发人员仅需要显式配置组件。 例如,当Seam将组件A注入为组件B的属性时,组件A的Seam名称默认为组件B中的接收者属性名称。Seam中有很多小东西。 总体结果是,Seam中的配置元数据比竞争的Java框架简单得多。 结果,大多数Seam应用程序都可以用少量的简单Java注释进行适当的配置。 开发人员将从降低的复杂性中受益,最终,在竞争的框架中开发的用于相同功能的代码行也少得多。

7.避免XML滥用

您可能已经注意到,Java注释在表达和管理Seam配置元数据中起着至关重要的作用。 这是通过设计使框架更易于使用而完成的。

在J2EE的早期,XML被视为配置管理的“圣杯”。 框架设计人员将各种配置信息(包括Java类和方法名)放入XML文件中,而无需考虑对开发人员的后果。 回想起来,这是一个很大的错误。 XML配置文件是高度重复的。 他们必须重复代码中已经存在的信息才能将配置连接到代码。 这些重复使应用程序容易出现小错误(例如,错误拼写的类名将在运行时显示为难以调试的错误)。 缺少合理的默认配置设置进一步加剧了此问题。 实际上,在某些框架中,伪装成XML的样板代码的数量可能会甚至甚至超过应用程序中实际Java代码的数量。 对于J2EE开发人员,这种XML的滥用通常称为“ XML地狱”。

企业Java社区已认识到XML滥用问题,并且已经非常成功地尝试用Java源代码中的注释替换XML文件。 EJB3是官方Java标准化组织在企业Java组件中促进注释使用的努力。 EJB3使XML文件完全可选,这绝对是朝正确方向迈出的一步。 Seam添加了EJB3批注,并将基于批注的编程模型扩展到整个Web应用程序。

当然,XML对于配置数据并不完全有害。 Seam设计人员认识到XML非常适合指定Web应用程序页面流或定义业务流程工作流。 XML文件允许我们集中管理整个应用程序的工作流程,而不是将信息分散在Java源文件中。 工作流程信息与源代码几乎没有关联-因此,XML文件不需要复制代码中已经可用的类型化信息。

8.专为测试而设计

Seam从头开始设计,易于测试。 由于所有Seam组件都只是带注释的POJO,因此很容易进行单元测试。 您可以只使用常规Java new关键字创建POJO的实例,然后在测试框架中运行任何方法(例如JUnit或TestNG)。 如果需要测试多个Seam组件之间的交互,则可以分别实例化这些组件,然后手动设置它们之间的关系(即,显式使用setter方法,而不是依赖于Seam的依赖项注入功能)。

对于整个Seam应用程序的集成测试,由于要在Seam容器中运行该应用程序,因此要稍微复杂一点。 Seam带有可嵌入的轻型容器,可帮助进行此类测试。 在您的测试框架中,您可以以编程方式加载Seam容器,然后运行测试。

9.强大的工具支持

工具支持对于专注于开发人员生产力的应用程序框架至关重要。 Seam随命令行应用程序生成器Seam Gen一起分发。SeamGen与Ruby-On-Rails中可用的工具非常相似。 它支持的功能包括:从数据库生成完整的CRUD应用程序,开发人员通过“编辑/保存/重新加载浏览器”操作快速访问Web应用程序,测试支持等。

但更重要的是,Seam Gen生成的项目可以与领先的Java IDE(例如Eclipse和NetBeans)直接使用。 使用Seam Gen,您可以立即开始使用Seam!

10.让我们开始编码!

简而言之,Seam简化了Java EE应用程序的开发人员开销,同时,添加了Java EE 5.0之外的强大新功能。 在下一部分(摘自本书的第2章)中,我们将向您展示一些实际的代码示例,以说明Seam的工作方式。 您可以从本书的网站http://www.michaelyuan.com/seam/找到本书中所有示例应用程序的源代码下载。

缝你好世界

JBoss Seam的最基本和最广泛使用的功能是成为EJB3和JSF之间的粘合剂。 Seam允许通过托管组件在两个框架之间进行无缝集成(无双关!)。 它将EJB3带注释的POJO(普通的Java对象)编程模型扩展到整个Web应用程序。 不再需要人为要求的JNDI查找,冗长的JSF支持bean声明,过多的Facade业务方法以及在层之间艰难地传递对象等。

继续在Seam中使用Java EE模式

在传统的Java EE应用程序中,某些设计模式是必需的,例如JNDI查找,组件的XML声明,值对象,业务外观。 Seam使用带注释的POJO消除了这些人工需求。 但是,当您的Seam应用程序中确实需要这些模式时,您仍然可以自由使用它们。

从概念上讲,编写Seam Web应用程序非常简单。 您只需要编写以下组件的代码:

  • 实体对象代表数据模型。 实体对象可以是Java Persistence API(JPA,又名EJB3持久性)中的实体Bean或Hibernate POJO。 它们会自动映射到关系数据库表。
  • JSF网页显示用户界面。 这些页面通过表单捕获用户输入并显示结果数据。 表单字段和数据显示表映射到实体bean或实体bean的集合。
  • EJB3会话bean或带注释的Seam POJO充当JSF网页的UI事件处理程序。 它们处理封装在实体bean中的用户输入,并生成数据对象以在下一步(或页面)中显示。

以上所有组件均由Seam管理,并在运行时自动注入到正确的页面/对象中。 例如,当用户单击一个按钮提交JSF表单时,Seam会自动解析表单字段并构造一个实体bean。 然后,Seam将实体bean传递到事件处理程序会话bean中,该事件处理程序会话bean也由Seam创建,以进行处理。 您无需在自己的代码中管理组件生命周期和组件之间的关系。 没有样板代码,也没有用于依赖性管理的XML文件。

在本章中,我们使用一个hello world示例来确切显示Seam如何将Web应用程序粘合在一起。 该示例应用程序的工作方式如下:用户可以在Web表单上输入她的名字,以向Seam说“你好”。 提交后,该应用程序会将其名称保存到关系数据库中,并显示所有向Seam表示问候的用户。 该示例项目位于本书的源代码下载的HelloWorld文件夹中。 要构建它,必须安装Apache ANT 1.6+(http://ant.apache.org/)。 进入helloworld目录并运行命令ant 。 构建结果是build / jars / helloworld.ear文件,您可以将其直接复制到JBoss AS实例的server / default / deploy目录中。 现在,启动JBoss AS,该应用程序可从URL http:// localhost:8080 / helloworld /获得

安装JBoss AS

要运行本书中的示例,建议您使用JEMS(JBoss企业中间件套件)GUI安装程序来安装与Seam兼容的JBoss AS版本。 可以从http://labs.jboss.com/portal/jemsinstaller/downloads下载JEMS安装程序。 如果您需要有关JBoss AS安装和应用程序部署的进一步帮助,请参考附录A, 安装和部署JBoss AS

欢迎使用示例应用程序作为模板来快速启动自己的Seam项目(请参阅附录B, 将示例应用程序用作模板 )。 或者,您可以使用命令行工具Seam Gen(请参见第4章, 快速应用程序开发工具 )为您自动生成项目模板,包括所有配置文件。 在本章中,我们将不会花费太多时间来解释源代码项目中目录结构的详细信息。 相反,我们专注于开发人员必须编写或设法构建Seam应用程序的代码和配置工件。 这样,您可以将知识应用于任何项目结构,而不必局限于我们的模板。

源代码目录

Seam应用程序由Java类和XML /文本配置文件组成。 在本书的示例项目中,Java源代码文件位于src目录中,网页位于view目录中,所有配置文件均位于resources目录中。 请参阅附录B“ 将示例应用程序用作模板”中的更多内容

1.创建数据模型

hello world应用程序中的数据模型只是具有名称id属性的Person类。 @Entity批注告诉容器将此类映射到关系数据库表,每个属性在表中均包含一列。 每个Person实例对应于表中的一行数据。 由于Seam是“例外配置”,因此容器仅将类名属性名用作表名和列名。 id属性上的@Id@GeneratedValue批注指示id列用于主键,并且其值由应用程序服务器针对保存到数据库中的每个Person对象自动生成。

@Entity
@Name("person")
public class Person implements Serializable {

private long id;
private String name;

@Id @GeneratedValue
public long getId() { return id;}
public void setId(long id) { this.id = id; }

public String getName() { return name; }
public void setName(String name) {this.name = name;}
}

Person类中最重要的注释是@Name注释。 它指定了Person bean应该在Seam下注册的字符串名称。 在其他Seam组件(例如,页面和会话Bean)中,您可以使用“人员”名称来引用此组件的托管 Bean。

2.将数据模型映射到Web表单

在JSF页面中,我们使用Person Bean来支持表单输入文本字段。 #{person.name}符号是指Seam组件上名为“ person”的组件的name属性,该组件是Person实体bean的一个实例。

<h:form>
Please enter your name:<br/>
<h:inputText value="#{person.name}" size="15"/><br/>
<h:commandButton type="submit" value="Say Hello"
action="#{manager.sayHello}"/>
</h:form>

在输入表单下面,JSF页面显示数据库中所有对Seam说“你好”的人。 人员列表存储在名为“ fans”的Seam组件中。 粉丝组件是一个List <Person>对象。 JSF dataTable遍历列表,并在一行中显示每个Person对象。 风扇符号是风扇列表的迭代器。 图2.1, Hello World网页显示了该网页。

<h:dataTable value="#{fans}" var="fan">
<h:column>
<h:outputText value="#{fan.name}"/>
</h:column>
</h:dataTable>

图2.1。 Hello World网页

当用户单击“问好”按钮提交表单时,Seam将使用输入数据创建人员管理的组件。 然后,它在名为“ manager”的 Seam组件上调用sayHello()方法(即, #{manager.sayHello}是表单提交按钮的UI事件处理程序),该方法将person对象保存到数据库并刷新粉丝列表。 管理器组件是一个EJB3会话bean,我们将在下一节中讨论它。

3.处理网络事件

Seam中的manager组件是ManagerAction会话bean,由类上的@Name注释指定。 该ManagerAction类与@In@Out注解的人球迷场。

@Stateless
@Name("manager")
public class ManagerAction implements Manager {

@In @Out
private Person person;

@Out
private List <Person> fans;

@In@Out注释是Seam编程模型的核心。 因此,让我们看看他们在这里所做的确切工作。

  • @In注释告诉Seam在执行会话bean中的任何方法之前,将由JSF表单数据组成的人员组件分配给人员字段(依赖注入)。 您可以在@In中为注入的组件指定一个任意名称。 但是,如果没有指定名称(如此处所示),Seam只会注入与接收字段变量相同类型和名称的组件。
  • @Out注解告诉Seam的球迷字段相同名称的管理组件分配值的任何方法执行后。 我们在Seam中将此动作称为“依赖排除”。 这样,在ManagerAction.sayHello()方法中,我们只需要更新粉丝人员字段值,它们将自动在网页上可用。
    • 什么是双射

      在Seam文档中,有时会看到术语“双射”。 这是指Seam组件与Seam受管上下文之间的双向注入和注入交互。

      由于人员字段已经通过注入包含表单数据,因此sayHello()方法仅通过通过@PersistenceContext批注注入的JPA EntityManager将其保存到数据库中。 然后,刷新在方法退出后被淘汰的粉丝人物对象。 sayHello()返回null,以指示在调用后将使用最新的模型数据重新显示当前JSF页面。

      @PersistenceContext
      private EntityManager em;

      public String sayHello () {
      em.persist (person);
      person = new Person ();
      fans = em.createQuery("select p from Person p")
      .getResultList();

      return null;
      }

      除了一件小事情,我们几乎完成了。 您可能已经注意到, ManagerAction bean类实现了Manager接口。 为了符合EJB3会话Bean规范,我们需要一个列出该Bean中所有业务方法的接口。 以下是Manager界面的代码。 幸运的是,很容易从任何现代IDE工具自动生成此接口。

      @Local
      public interface Manager {
      public String sayHello ();
      }

      这就是Hello World示例所需的全部代码。 在接下来的两节中,我们将介绍其他替代方法以及Seam应用程序的配置。 如果您想直接跳入代码并为自己的小型数据库应用程序定制helloworld项目,则可以暂时跳过本章的其余部分。

      4.更好地理解接缝编程模型

      现在,我们匆匆浏览了Hello World示例应用程序。 但是,我们省略了一些重要的主题,例如其他处理方式和上述代码未涵盖的重要功能。 在本节中,让我们浏览这些主题。 它们可以帮助您更深入地了解Seam。 但是,如果您没有耐心,可以跳过本节,稍后再返回。

      4.1。 接缝POJO组件

      在上面的示例中,我们使用EJB3会话bean来实现应用程序逻辑。 但是我们不限于在Seam中使用EJB3组件。 实际上,在Seam中,任何带有@Name批注的POJO都可以变成托管组件。

      例如,我们可以使ManagerAction成为POJO而不是EJB3会话bean。

      @Name("manager")
      public class ManagerAction {

      @In (create=true)
      private EntityManager em;

      ... ...
      }

      使用POJO替换EJB3 bean具有优缺点。 POJO稍微更易于编程,因为它们不需要特定于EJB3的注释和接口(请参见上文)。 如果所有业务组件都是Seam POJO,则可以在EJB3应用程序服务器之外运行Seam应用程序(请参阅第23章, 没有EJB3的Seam )。

      但是,由于POJO无法获得EJB3容器服务,因此POJO的功能也少于EJB3组件。 在非EJB3 Seam POJO中丢失的EJB3服务示例包括以下内容。

      • @PersistenceContext注入在POJO中不再起作用。 为了在Seam POJO中获得EntityManager ,您必须在Seam配置文件中初始化EntityManager ,然后使用Seam @In批注将其注入POJO。
      • POJO中不支持声明式方法级事务。 相反,您可以将Seam配置为从接收Web请求到呈现响应页面时对数据库事务进行划分。
      • Seam POJO不能是消息驱动的组件。
      • 不支持@Asynchronous方法。
      • 不支持容器管理的安全性。
      • 没有事务或组件级别的持久性上下文。 Seam POJO中的所有持久性上下文都是“扩展的”(有关更多详细信息,请参见第7.1节“默认会话范围”)。
      • 没有集成到容器的管理体系结构(即JMX控制台服务)中。
      • 没有Java远程(RMI)到Seam POJO方法。
      • Seam POJO不能是@WebService组件。
      • 没有JCA集成。

      那么,为什么有人在EJB3容器中部署时想使用POJO组件? 好的,POJO组件非常适合纯“业务逻辑”组件,该组件将数据访问,消息传递和其他基础结构功能委托给其他组件。 例如,我们可以使用POJO组件来管理Seam数据访问对象。 “业务逻辑” POJO非常有用,因为如果需要,它们可以在其他框架中重复使用。 但是总而言之,它们的应用程序比EJB3组件小得多,尤其是在中小型应用程序中。 因此,在本书中的大多数示例中,我们都使用EJB3组件。

      4.2。 易于测试

      正如我们在第1章“ 什么是Seam”中提到的那样,Seam是从头开始构建的,从而可以轻松进行容器外的测试。 在helloworld项目中,我们在测试文件夹中包含了两个用于单元测试和集成JSF测试的测试用例 。 Seam测试基础结构在纯Java SE环境中模拟数据库,JSF,Seam上下文和其他应用程序服务器服务。 只需运行ant test即可运行这些测试。

      4.3。 基于Getter / Setter的双射

      在Hello World示例中,我们演示了如何将Seam组件与字段变量进行对分。 您还可以根据getter和setter方法对组件进行双向处理。 例如,以下代码可以正常工作。

      private Person person;
      private List <Person> fans;

      @In
      public void setPerson (Person person) {
      this.person = person;
      }
      @Out
      public Person getPerson () {
      return person;
      }
      @Out
      public List <Person> getFans () {
      return fans;
      }

      尽管上面的getter / setter方法很简单,但通过getter / setter方法进行双向注入的真正价值在于,您可以添加自定义逻辑来操纵双向注入过程。 例如,您可以验证注入的对象或从数据库中即时检索注入的对象。

      4.4。 避免过多的双射

      依赖关系双射是一种非常有用的设计模式。 但是,像任何其他设计模式一样,始终存在过度使用它的危险。 过多的依赖关系双射会使代码更难阅读,因为开发人员必须从头脑中弄清楚每个组件从何处注入。 由于双射发生在运行时,所以过多的双射也会增加性能开销。

      在“ Hello World”示例中,有一种简单的方法可以减少甚至消除双目:仅使业务组件的数据组件属性成为可能。 这样,在JSF页面中,我们只需要引用业务组件,就不需要将业务和数据组件联系在一起的双向对象。 例如,我们可以将ManagerAction类更改为以下内容。

      @Stateless
      @Name("manager")
      public class ManagerAction implements Manager {

      private Person person;
      public Person getPerson () {return person;}
      public void setPerson (Person person) {
      this.person = person;
      }

      private List <Person> fans;
      public List<Person> getFans () {return fans;}

      ... ...
      }

      然后,在网页上,我们按如下方式引用属性。

      <h:form>

      Please enter your name:<br/>

      <h:inputText value="#{manager.person.name}"/>
      <br/>
      <h:commandButton type="submit" value="Say Hello"
      action="#{manager.sayHello}"/>
      </h:form>
      ... ...
      <h:dataTable value="#{manager.fans}" var="fan">
      <h:column>
      <h:outputText value="#{fan.name}"/>
      </h:column>
      </h:dataTable>

      最重要的是,在依赖管理方面,Seam具有多种用途。 通常,将数据组件与其数据访问业务组件封装在一起是一种好习惯。 有状态业务组件尤其如此。

      4.5。 JSF中的页面导航

      在此示例中,我们有一个页面应用程序。 每次单击按钮后,JSF都会用更新的数据模型值重新呈现该页面。 显然,大多数Web应用程序将具有多个页面。 在JSF中,UI事件处理程序方法可以通过返回导航规则的字符串名称来确定接下来要显示的页面。 例如,您可以在navigation.xml文件中定义以下导航规则。

      <navigation-case>
      <from-outcome>anotherPage</from-outcome>
      <to-view-id>/anotherPage.jsp</to-view-id>
      </navigation-case>

      然后,如果sayHello()方法返回字符串值“ anotherPage” ,那么JSF将在下一个显示anotherPage.jsp页面。 这使我们可以从UI事件处理程序方法内部以编程方式控制接下来要显示哪个页面。

      4.6。 通过EntityManager访问数据库

      JPA(Java持久性API,又名EJB3实体Bean持久性) EntityManager管理关系数据库表和实体Bean对象之间的映射。 EntityManager由应用程序服务器在运行时创建。 您可以使用@PersistenceContext批注注入EntityManager实例。

      EntityManager.persist()方法将实体bean对象保存为其映射关系表中的一行。 EntityManager.query()方法运行类似于SQL的查询,以实体Bean对象集合的形式从数据库中检索数据。 有关如何使用EntityManager和查询语言的更多信息,请参考JPA文档。 在本书中,我们仅使用最简单的查询。

      默认情况下, EntityManager将数据保存到嵌入式HSQL数据库。 如果您正在本地计算机上的JBoss AS中运行该应用程序,则可以通过以下步骤打开HSQL数据库的GUI控制台:转至页面http:// localhost:8080 / jmx-console / ,单击数据库= localDB,service = Hypersonic MBean,然后单击startDatabaseManager方法下的“调用”按钮。 您可以从控制台对数据库执行任何SQL命令。

      5.配置和包装

      接下来,让我们继续进行配置文件和应用程序打包。 实际上,您可以通过Seam Gen命令行实用程序生成几乎所有的配置文件和构建脚本,或者可以简单地在示例应用程序源项目中重复使用这些配置文件。 因此,如果您想先学习Seam编程技术,然后再担心配置/部署,那很好。 您可以放心地跳过此部分,并在需要时稍后返回。

      在本节中,我们在这里重点介绍Seam EJB3组件的配置。 当然,也可以在JBoss AS外部进行Seam POJO的配置和部署。

      大多数Seam配置文件都是XML文件。 可是等等! 我们不是只是承诺Seam将使我们脱离J2EE和Spring中的“ XML地狱”吗? 为什么也有XML文件? 事实证明,XML文件有一些很好的用法! XML文件非常适合部署时间配置(例如,Web应用程序的根URL和后端数据库的位置),因为它允许我们在不更改和重新编译代码的情况下进行部署时更改。 它们有利于将应用程序服务器中的不同子系统粘合在一起(例如,配置JSF组件与Seam EJB3组件的交互方式); XML文件也适合与演示相关的内容(例如,网页和页面导航流程)。

      我们反对将Java源代码中已经存在的信息复制到XML文件中。 您将很快看到,这个简单的Seam应用程序具有多个XML配置文件。 它们都非常短,并且都不涉及Java代码中已经可用的信息。 换句话说,Seam中没有“ XML代码”。

      此外,这些XML文件中的大多数内容都是相当静态的。 因此,您可以轻松地将这些文件重用于自己的Seam应用程序。 请参阅附录B, 将示例应用程序用作模板,以获取有关如何将示例应用程序用作自己的应用程序模板的说明。

      我们将在接下来的几页中详细介绍示例应用程序的配置文件和打包结构。 如果您不耐烦并且对应用程序模板感到满意,则可以跳过这些。 无论如何,不​​用费劲,让我们研究一下hello world示例应用程序是如何配置和打包的。 要为JBoss AS构建可部署的Seam应用程序,我们必须将上述所有Java类和配置文件打包在Enterprise Application aRchive(EAR)文件中。 在此示例中,EAR文件是helloworld.ear 。 它包含三个JAR文件和两个XML配置文件。

      helloworld.ear
      |+ app.war // Contains web pages etc.
      |+ app.jar // Contains Seam components
      |+ jboss-seam.jar // The Seam library
      |+ META-INF
      |+ application.xml
      |+ jboss-app.xml

      源代码目录

      在源代码项目中, resources / WEB-INF目录包含进入app.war / WEB-INF的配置文件; resources / META-INF目录包含进入app.jar / META-INFhelloworld.ear / META-INF的文件resources目录根目录中的文件都位于app.jar的根目录中。

      application.xml文件列出了EAR中的JAR文件,并指定了此应用程序的根URL。

      <application>
      <display-name>Seam Hello World</display-name>

      <module>
      <web>
      <web-uri>app.war</web-uri>
      <context-root>/helloworld</context-root>
      </web>
      </module>

      <module>
      <ejb>app.jar</ejb>
      </module>

      <module>
      <java>jboss-seam.jar</java>
      </module>

      </application>

      jboss-app.xml文件指定此应用程序的类加载器。 每个EAR应用程序对于类加载器应具有唯一的字符串名称。 在这里,我们在类加载器名称中使用应用程序名称,以避免重复。

      <jboss-app>
      <loader-repository>
      helloworld:archive=helloworld.ear
      </loader-repository>
      </jboss-app>

      jboss-seam.jar文件是Seam发行中的Seam库JAR文件。 app.warapp.jar文件由我们构建。 因此,接下来让我们看看app.warapp.jar文件。

      5.1。 WAR文件

      app.war文件是打包到Web应用程序获取(WAR)规范的JAR文件。 它包含网页以及标准的JSF / Seam配置文件。 您还可以将JSF特定的库文件放在WEB-INF / lib目录中(例如jboss-seam-ui.jar )。

      app.war
      |+ hello.jsp
      |+ index.html
      |+ WEB-INF
      |+ web.xml
      |+ faces-config.xml
      |+ components.xml
      |+ navigation.xml

      所有Java EE Web应用程序都需要web.xml文件。 JSF使用它来配置JSF控制器servlet,而Seam使用它来拦截所有Web请求。 该文件中的配置是非常标准的。

      <web-app version="2.4"
      xmlns="http://java.sun.com/xml/ns/j2ee"
      xmlns:xsi="..."
      xsi:schemaLocation="...">

      <!-- Seam -->
      <listener>
      <listener-class>
      org.jboss.seam.servlet.SeamListener
      </listener-class>
      </listener>

      <!-- MyFaces -->
      <listener>
      <listener-class>
      org.apache.myfaces.webapp.StartupServletContextListener
      </listener-class>
      </listener>

      <context-param>
      <param-name>
      javax.faces.STATE_SAVING_METHOD
      </param-name>
      <param-value>client</param-value>
      </context-param>

      <servlet>
      <servlet-name>Faces Servlet</servlet-name>
      <servlet-class>
      javax.faces.webapp.FacesServlet
      </servlet-class>
      <load-on-startup>1</load-on-startup>
      </servlet>

      <!-- Faces Servlet Mapping -->
      <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>*.seam</url-pattern>
      </servlet-mapping>
      <context-param>
      <param-name>javax.faces.CONFIG_FILES</param-name>
      <param-value>/WEB-INF/navigation.xml</param-value>
      </context-param>
      </web-app>

      faces-config.xml文件是JSF的标准配置文件。 Seam使用它将Seam拦截器添加到JSF生命周期中。

      <faces-config>

      <lifecycle>
      <phase-listener>
      org.jboss.seam.jsf.SeamPhaseListener
      </phase-listener>
      </lifecycle>

      </faces-config>

      navigation.xml文件包含用于多页面应用程序的JSF页面导航规则。 由于hello world示例只有一个页面,因此此文件为空。

      components.xml文件包含特定于Seam的配置选项。 除jndi-pattern属性外,它还几乎与应用程序无关,该属性必须包括EAR文件的基本名称,Seam才能通过其完整的JNDI名称访问EJB3 bean。

      <components ...>

      <core:init
      jndi-pattern="helloworld/#{ejbName}/local"
      debug="false"/>

      <core:manager conversation-timeout="120000"/>

      </components>
      5.2。 接缝组件JAR

      app.jar文件包含所有EJB3 bean类(实体bean和会话bean)以及EJB3相关的配置文件。

      app.jar
      |+ Person.class // entity bean
      |+ Manager.class // session bean interface
      |+ ManagerAction.class // session bean
      |+ seam.properties // empty file but needed
      |+ META-INF
      |+ ejb-jar.xml
      |+ persistence.xml

      seam.properties文件在此处为空,但是JBoss必须知道该JAR文件包含Seam EJB3 bean类,并相应地处理注释。

      ejb-jar.xml文件包含可以覆盖或补充EJB3 Bean上的注释的其他配置。 在Seam应用程序中,它将Seam拦截器添加到所有EJB3类中。 我们可以为所有Seam应用程序重用同一文件。

      <ejb-jar>
      <assembly-descriptor>
      <interceptor-binding>
      <ejb-name>*</ejb-name>
      <interceptor-class>
      org.jboss.seam.ejb.SeamInterceptor
      </interceptor-class>
      </interceptor-binding>
      </assembly-descriptor>
      </ejb-jar>

      persistence.xml文件为EJB3实体bean配置后端数据库源。 在此示例中,我们只使用嵌入在JBoss AS中的默认HSQL数据库(即java:/ DefaultDS数据源)。

      <persistence>
      <persistence-unit name="helloworld">
      <provider>
      org.hibernate.ejb.HibernatePersistence
      </provider>
      <jta-data-source>java:/DefaultDS</jta-data-source>
      <properties>
      <property name="hibernate.dialect"
      value="org.hibernate.dialect.HSQLDialect"/>
      <property name="hibernate.hbm2ddl.auto"
      value="create-drop"/>
      <property name="hibernate.show_sql" value="true"/>
      </properties>
      </persistence-unit>
      </persistence>

      因此,这就是一个简单的Seam应用程序所需的配置和打包。 当我们转到本书的更高级主题时,我们将介绍更多配置选项和库文件。 同样,启动Seam应用程序的最简单方法是完全不用担心那些配置文件,而从一个现成的应用程序模板开始。

      6.这个简单吗?

      Hello World应用程序就是这样。 通过三个简单的Java类,一个JSF页面和许多静态配置文件,我们有了一个完整的数据库驱动的Web应用程序。 整个应用程序需要少于30行的Java代码,并且不需要“ XML代码”。 但是,如果您来自PHP背景,您可能仍然会问:“这有多简单?我可以用更少的代码在PHP中完成!”

      好吧,答案是Seam应用程序在概念上比PHP(或任何其他脚本语言)应用程序简单得多。 Seam组件模型使我们能够以可控和可维护的方式向应用程序添加更多功能。 正如我们将很快看到的,Seam组件使开发有状态和事务性Web应用程序变得轻而易举。 对象关系映射框架(即实体Bean)使我们可以专注于抽象数据模型,而不必处理特定于数据库SQL语句。

      本文基于第一章和第二章的摘录-在本书的其余部分中,我们将讨论如何使用Seam组件开发日益复杂的Seam应用程序。 另请参阅目录,其中显示了本书中的所有主题。

      另请参阅先前有关Seam的新闻文章对Seam创作者Gavin King的两次采访:

      翻译自: https://www.infoq.com/articles/jboss-seam/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

      jboss seam

    • 1
      点赞
    • 1
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值