创建EJB组件

816-7864-10

Table of Contents Table of Contents Next Chapter

第8章


准备部署企业 Bean

翻译:Sundoc_Smiling:FlyBean

  前面的章节着重于创建单独的企业 Bean。然而,在将一个已完成的企业 Bean装配到应用中,并且部署于产品环境之前,还需要做下面三件事情:

1.      提供有关 Bean 的外部依存关系和运行环境的某些信息。这些信息将成为企业 Bean 的部署描述符的一部份。这将在下一节中论述;

2.      将应用中众多的、需要协作工作的企业 Bean 组成 EJB 模块。同样,如果必要,为每一个 EJB 模块添加一个EJB JAR 文件;

3.      使用 Sun Java System Studio IDE 的自动测试特性,测试您的企业 Bean 及模块。

通常,企业 Bean 是装配进 EJB 模块的;一个或多个 EJB 模块装配进一个应用;应用部署到应用服务器。然而,也可以部署一个单独的 EJB 模块。

本丛书中的另一部文档,《构建 J2EE 应用》Building J2EE Applications)详细论述了应用的设计和装配,以及将它们部署到服务器上。


理解部署信息

您在企业 Bean 的属性页提供的部署信息将成为它的部署描述符的一部份。部署描述符是一个基于 XML 的文本文件,它保存有关 Bean 的结构、与其它 Bean 的关系,以及其它外部依存关系的信息。部署描述符包含了在部署企业 Bean 的应用时,应用服务器需要知道的所有说明。对描述符的任何改动都可能改变应用中企业 Bean 的行为。

当您按照前面章节所描述的步骤,使用 EJB Builder 向导创建 Bean 时,(IDE)自动地为该企业 Bean 启动了一个部署描述符。向导自动产生了 Bean 的基本描述符。

当您将企业 Bean 放入 EJB 模块中时(在创建 EJB 模块中说明),IDE 同样自动地为模块产生一个部署描述符。这个部署描述文件保存以下信息:

l        来自企业 Bean 部署描述符的每个企业 Bean 的声明元信息(更确切地说,并不出现在代码中,关于 Bean 的信息)。

l        关于如何将企业 Bean 融入(模块为之设计的)应用和部署中的高级信息。

l        安全和事务信息。它们允许 EJB 模块在 Bean 层次上重置(override)已指定的那些(安全和事务)信息。

l        为容器准备的、关于实体 Bean 所使用的数据源的说明。

通过改变 EJB 模块的描述符,允许您无需修改 Bean 组件,就可以改变应用的行为。

您可以通过相应 Bean 或模块的属性页来访问部署描述符的内容。如果需要,您也可以直接编辑 EJB 模块的描述符。下面三节将告诉您如何查看及影响部署描述符。

查看已产生的部署描述符

查看组成企业 Bean 的部署描述符的、基于 XML 的文件:

l        Explorer 窗口,选择企业 Bean 的逻辑节点,点击鼠标右键,选择 View Deployment Descriptor(查看部署描述符)(或者,选择 EJB 模块的逻辑节点,点击鼠标右键,选择 Deployment Descriptor right arrow View)。

源代码编辑器以只读形式显示该文件。

编辑 EJB 模块的部署描述符

通常,您只能通过 Bean EJB 模块的属性页,来编辑 EJB 模块的部署描述符(在下一节描述)。当您使用 Properties 窗口来编辑此文件时,您所需做的一切仅仅是指定文件名和值(以及,如果是实体 Bean 的话,可能的表名和列名)。您不用编写任何 XML 代码。您只需使用对话框来选择,IDE 自动在企业 Bean 的适当的类之间同步您所做的修改。

当然,您也可以直接修改部署描述符,编辑后您可以还原(revert)为之前产生的描述符。

直接编辑 EJB 模块的部署描述符

如果您需要编辑 EJB 模块的部署描述文件,您可以按照下面所述内容执行:

l        鼠标右键点击 EJB 模块节点,并选择 Deployment Descriptor right arrow Final Edit(最终编辑)。

直接编辑 EJB 模块的部署描述文件后,您仍可以使用属性页,做一些不影响部署描述符的修改。例如,您仍然可以进入 J2EE RI 标签面板,指定或改变 Data Source JNDI Name(数据源 JNDI 名称)、Data Source Password(数据源密码)以及 Data Source User Name(数据源用户名)域(请小心,不要编辑那些既出现在属性页,又出现在部署描述符中的域)。当然,那些表示部署描述符的选项是集中在属性页中编辑的。

还原 EJB 模块最后一次产生的描述符

如果您使用了 Final Edit 特性,但是想退回为最后一次产生的部署描述符,并使用属性页继续修改,那么,按下面所述内容执行:

l        鼠标右键 EJB 模块节点,选择 Deployment Descriptor right arrow Revert to Generated(还原)


注意——如果您选择了Revert to Generated,那么,部署描述符中,您所做的任何改动都将丢失。


使用 Properties(属性)编辑部署描述符

按下面所述内容,增加、编辑或完成企业 Bean EJB 模块的描述符:

l        选择 Bean EJB 模块的逻辑节点,点击鼠标右键,然后选择 Properties

如果是企业 Bean,出现 Properties能对话框,至少显示三个标签面板:

  • Properties(属性)
  • References(引用)
  • J2EE RI Java trademark 2 平台企业版的参考实现服务器)

如果在 IDE 中安装其它应用服务器的 Plug-in 模块,那么您也将看到相应的标签面板。

如果是 EJB 模块,那么有两个默认的标签面板:Properties(包括引用域)和 J2EE RI

下一步将描述企业 Bean 的三个默认的标签面板。


指定 Bean 的属性

在用企业 Bean 创建 EJB 模块之前,您需要指定每个 Bean 的属性。下面的几节将一个面板一个面板地详述这些属性: 使用 Properties 标签面板使用 References 标签面板以及使用 J2EE RI 标签面板

使用 Properties 标签面板

由于您熟悉 Bean 的代码,因此您或许能识别在 Properties 标签面板中出现的大多数的域。同样请注意下面这些:

  • 不论是何种企业 Bean,在 Properties 面板中都有一些域是只读的。这些域是在您创建 Bean 时,由 EJB Builder 向导自动完成的。这些域指定的属性是 Bean 类型所固有的,因此您不需要修改它们。修改这些属性的唯一实际的方法是回到创建向导,重新创建 Bean
  • Name 域和命名 Bean 的接口的那些域是您在创建 Bean 时,由EJB Builder 向导自动产生的(或者是在创建时,您重置了那些域的名称)。

如果您希望 Bean 使用另一个已经存在的类,您可以重置其中一个 Properties 域所显示的类。

如果您希望改变一个类的类名,同时保留相同的内容,那么,您必须要么在该类的属性编辑器中修改(而不是 Bean 的逻辑节点),要么直接在源代码编辑器中修改类的代码。

  • Large Icon(大图标)和 Small Icon(小图标)域可使用任何图标,它们作为企业 Bean 的附加部份,可以被诸如应用服务器之类的工具使用。对于大图标而言,文件必须是 32x32 像素大小的 JPEG GIF 图像。对于小图标而言,是 16x16 像素大小。文件的后缀必须是 .jpg .gif
  • Security Identity(安全身份)域允许您指定企业 Bean 调用其它组件时所使用的身份:
    • 如果您选择 Run As Specific Security Role(以指定的安全角色运行)并且命名了一个角色,例如,一个相关的 Bean 中的角色,那么,Bean 将在该安全角色下执行,并且此 Bean 调用的所有方法都持有(carry)该角色。通过这种方式,Bean 可以访问通常只能由其它 Bean 访问的数据。或者,您可以在此处指定 Bean 的默认安全角色。
    • 如果您选择了 Use Caller's Security Identity(使用调用者的安全身份),那么,Bean 在执行时采用调用者的安全身份。
    • 如果您选择了 Not Set (不设置),那么 Bean 是在应用服务器级定义的安全身份之下,或者是在调用者的安全身份这下执行的。

对于特定的 Bean 类型而言,此标签面板中的一些属性类型是特殊的。接下来,我们将详述这些属性。

实体 Bean 的属性

在任何实体 Bean Properties 面板,您都可以看到以下域:

  • Primary Key Class(主键类):如果您想改变 EJB Builder 向导所产生的此域的值,您可以选择已有的域、声明未知的主键类,或者是选择已有的用户定义的类。
  • Reentrant(重入): 如果您想避免无意之中出现的多线程问题,就让此域为 False。这样,如果在给定的事务上下文中,Bean 的一个实例执行一个客户端请求时,同一个实体对象收到申请相同的上下文的请求,那么容器将向第二个请求抛出异常。然而,如果的确需要 Bean 使用另一个 Bean 回调自身,那么,将此域置为 True

CMP 实体 Bean Properties 面板中,您还将看到以下域:

  • Abstract Schema Name(抽象模式名):抽象模式定义 Bean 的持久域和关系。CMP 实体 Bean EJB QL 查询语句模型化了 Bean 的抽象持久模式(abstract persistence schema)和它所依靠的对象的类。
  • CMP Version.CMP 版本):只读域,反映该 CMP Bean 的版本是 1.x  还是 2.x

会话 Bean 的属性

在会话 Bean Properties 面板,您将看到以下域:

  • Bean TypeBean 类型):如果您需要,您可以将它的值由 Stateless(无状态) 改变为 Stateful(有状态)(或相反)。
  • Transaction Type(事务类型):此域表明是容器还是 Bean 自己管理事务。如果您改变了它的值,EJB Builder将在代码中搜寻,完成相应的改动。

消息驱动 Bean 的属性

在消息驱动 Bean Properties 面板,您将看到以下域:

  • Transaction Type(事务类型):此域表明是容器还是 Bean 自己管理事务。EJB 向导自动为该域赋值。如果必要,您可以改变它的值。
  • Acknowledge Mode(确认模式):.如果消息驱动 Bean 的事务类型是 Bean 管理型,您将看到 Acknowledge Mode 属性出现在标签面板中。设置该属性的值为 Auto(自动),确保 Bean 所使用(消费)的所有消息都得以确认。或者,如果您希望 Bean 自己确认重复的消息,那么将该域的值设为 Duplicates Allowed(允许重复确认)。
  • Message Selector(消息选择器):如果您希望提供一个或多个过滤器,减少消息驱动 Bean 必须监听的消息数量,那么您就可以使用此域。例如,下面的字符导致 Bean 只接收 AccountStatus 属性设置为 Late Delinquent 消息。AccountStatus = `Late' OR AccountStatus = `Delinquent' 消息选择器的语法是基于 SQL 92 条件表达语法(conditional expression syntax)的一个子集的。在 JMS 规范和JMS 教程中作了详细的描述。
  • Message-Driven Destination(消息驱动接收者): 此域指定消息驱动 Bean 是监听消息队列,还是订阅主题(以及在这种情况下,订阅是持久的还是非持久的)。此域的数据是与应用服务器的属性页的标签接口中的某些域相互联系的。在此域中,您所输入的必须与您在 J2EE RI 标签面板中的Connection Factory Name(连接工厂名)、Destination JNDI Name(接收者 JNDI 名称),以及 Durable Subscription Name(持久订阅名称)等域中的值一致。详细信息,参见为消息驱动 Bean 设置 J2EE RI 属性

使用 References(引用)标签面板

在准备装配和部署企业 Bean 之前,您必须完成这个标签面板中的域。这些域代表了企业 Bean 的外部依存关系。其中的一些信息可以在 Bean 级声明,然后在模块级或应用级重置。

下面展示了一个 References 标签面板。

 8-1 CMP 实体 Bean 的属性对话框中的 References 标签面板

Screenshot showing the References tabbed pane of a CMP entity bean's property sheet.

下面将描述面板中的每个域,并说明如何完成这些域。

指定 EJB 本地引用

该域和后面一个域包含了任何其它 Bean 的相关信息。它们的方法将被当前 Bean 调用。使用 EJB Local References 域,指定同一个 JVM 内对 Bean 的引用。EJB 本地引用访问运行在同一个 JVM 中的 Bean 的本地接口,即使它们位于不同的 EJB 模块(请对比指定 EJB 引用)。

您可以在开发时就指定实现的企业 Bean 的名称。当然,如果必要,在 Bean装配进 EJB 模块时,可以重置其设置。

Bean 的代码中,使用 JNDI 接口查找另一个 Bean Home 接口。在将 Bean 封装进 EJB 模块之前,通过在 Bean 的属性页指定相同的引用,将企业 Bean 连接起来。应用装配者必须检查 EJB 引用域,查看根据设计,哪些 Bean 是必须被(当前)Bean 访问的。部署时,可以使用此处在 Bean 级上指定的引用,也可以在模块级上重置。这是由目标环境决定的。

在将多个 Bean 封装进 EJB 模块之前,需要将引用写入 Bean 类的代码中,并在属性页中指定 EJB 引用。

按下面的步骤,在属性页中指定 EJB 本地引用:

1. 点击 the EJB Local References 域,然后点击省略号按钮。

出现 EJB Local References 属性编辑器。

2. 点击 Add

出现 Add EJB Local Reference(增加 EJB 本地引用)对话框。

3. 完成这些域。

下面所列出的域是必填的:


注意——填写这些域的最简单的方法是,从 Referenced EJB Name(引用的 EJB 名称)域开始,从 Browse 列表中选择一个本地 EJB Bean。之后,IDE将自动填写类型域和其它两个接口域。当然,如果需要,您也可以修改接口域。


  • Reference Name(引用名称):被引用的 Bean 名称,与 Bean 代码中 context.lookup 方法调用所使用的名称相同。注意,该域早已包含了 ejb/。它相对于 java:comp/env 上下文的 ejb/ 子上下文。在斜线后输入您所想引用的 Bean 名称。

例如, Account 可能查找 DiscountCodeTbl Home 接口。在这种情况理,完整的引用名称可以是 ejb/DiscountCodeTblHome,或者使用其它引用名称,只要与 JNDI 查找代码中所使用的名称一致。

  • Referenced EJB Name(被引用的 EJB 名称):实现了在这些域中指定的本地 Home 和本地接口的企业 Bean 的名称。根据您的实际情况,您可以选择下面其中任何一种方法:
    • 点击 Browse,选择企业 Bean。在这种情况下,IDE自动为您完成 Local Home Interface Local Interface 域。
    • 在域中输入数据,指定其它实现了相同的接口的 Bean,然后改变引用,指向另一个 Bean
    • 在将 Bean 装配进 EJB 模块或应用之前,就让此域为空。
  • Type(类型):被引用的 Bean 是会话 Bean 还是实体 Bean
  • Local Home Interface(本地 Home 接口):被引用的 Bean 的本地 Home 接口。
  • Local Interface(本地接口):被引用的 Bean 的本地接口。

描述域是可选的。输入的信息应能充分帮助装配者,因为他们负责将 EJB 模块装配进应用。

  • Description(描述):说明 Bean 的作用,或说明为什么要引用它。

指定 EJB 引用

EJB 引用域,指定到任何企业 Bean 的连接。这些 Bean 可以不在当前 Bean JVM 环境之中,但当前 Bean需要调用它们的方法。除了您所命名的引用是指向在另一个 JVM 运行的远程接口外,您可以按照 EJB 本地引用域那样来使用此域。

指定环境选项

环境选项是命名的数据值。它保存于 Bean 的运行环境中,并依赖于部署站点的策略和过程。环境选项可以在部署时改变企业 Bean 的行为,而无须修改 Bean 的源代码。您在属性页设置的任何值,都可以在部署时,在 EJB 模块或应用的部署描述符中重置。

例如,Account Bean 可以使用环境选项 overdraftAllowedboolean类型)。此变量可能指出,使用该 Bean 的某个特定的银行允许消费者透支。Account 查找 overdraftAllowed 的值,决定如果消费者的请求导致透支,它将如何处理。

按下面的步骤,添加环境选项:

1. 点击 Environment Entry 域,然后点击省略号按钮。

出现 Environment Entry Properties(环境选项属性)编辑器。

2. 点击 Add

出现 Add Environment Entry(增加环境选项)对话框。

3. 完成这些域。

以下两个域是必填的:

  • Name(名称): 环境变量的名称。
  • Type(类型):环境变量的数据类型。

您也可以完成另两个域:

  • Description(描述):变量的作用,以及装配者和部署者需要知道的任何相关信息。
  • Value(值): 初始值。

指定资源环境引用

使用此域指定企业 Bean 需要使用的任何管理对象(administered object),如 JMS 接收者(队列或主题)。资源环境引用是队列或主题的逻辑名称。逻辑名称必须映射到在 Bean 类代码中InitialContext.lookup 方法所使用的名称。当 Bean 需要您在此域所指定的资源时,资源工厂将创建一个该资源的实例。在下一节,将涉及资源工厂。

按下面的步骤,添加 Bean 要使用的每一个资源引用:

1. 点击 Resource Environment Reference(资源环境引用)域,然后点击省略号按钮。

出现 Resource Environment References 属性编辑器。

2. 点击 Add

出现 Add Resource Environment Reference 对话框。

3. 完成这些域。

下面的域是必填的:

  • Name(名称): 出现在 Bean 类代码的 InitialContext.lookup 方法中的名称
  • Type(类型):. 资源工厂的类型。指定您自己的类型,或者选择以下类型:
    • javax.jms.QueueJMS 队列;
    • javax.jms.TopicJMS 服务主题。

指定资源引用

该域包含了 Bean 所需要的与资源的连接工厂的名称。资源可以是数据源(比如关系数据库)、管理对象(比如队列或主题)、JavaMail 会话、URL或者是 J2EE 连接器(通过它,Bean 可以连接其它应用系统或 EIS)。资源引用域的信息必须与 Bean 类代码中 JNDI 方法调用所使用的名称一致。

按下面的步骤,添加 Bean 所需要的每一个资源:

1. 点击 Resource Factory Reference(资源工厂引用)域,然后点击省略号按钮。

出现 Resource Factory References 属性编辑器。

2. 点击 Add

出现 Add Resource Reference 对话框。

3. 完成这些域。

下面的域是必填的:

  • Name(名称):出现在 Bean 类代码 InitialContext.lookup 方法中。例如,对于命名为 myDatabase JDBC 资源工厂,lookup 方法可能是如下编码的:
javax.naming.InitialContext myContext = 
        new javax.naming.InitialContext(); 
javax.sql.DataSource mySource = (javax.sql.DataSource)
        myContext.lookup("java:comp/env/jdbc/myDataBase"); 

在这种情况下,资源引用相应的名称应该是 jdbc/myDataBase。注意:环境的子上下文是由 jdbc/ 表示的。

  •         Type(类型):资源工厂的类型。指定您自己的类型,或选择以下之一:
    • javax.sql.DataSourceJDBC 连接工厂;
    • javax.jms.QueueConnectionFactoryJMS 连接工厂;
    • javax.jms.TopicConnectionFactoryJMS 服务连接工厂;
    • javax.mail.SessionJavaMail 会话工厂;
    • javax.resource.cci.ConnectionFactory如果您希望企业 Bean 连接其它应用系统或 EIS,那么您必须自己声明的连接工厂。企业 Bean 可以使用 Connector 架构的 Common Client Interface CCI,通用客户端接口) API 以及资源适配器访问外部数据。关于如何在应用中实现 CCI API 的更多信息,请参考《Java 2 平台,企业版教程》(Java 2 Platform, Enterprise Edition Tutorial)。
    • java.net.URLURL 连接工厂。
  • Authorization(认证):为了使用资源,使用者是如何被认证及授权的:
    • Container(容器):EJB 容器使用应用部署者在部署时提供的信息来访问资源管理器。
    • Application(应用):EJB程序中用编程的方式指定与资源管理者连接所需的信息。

下面的域是可选的:

  • Sharing Scope(共享范围):与资源的连接是否是可以被同一个应用中的其它企业 Bean 共享。如果在同一事务上下文中,两个或更多的 Bean 可能使用相同的资源,那么容器可以从本地获取资源,从而节省时间。

指定Security-Role References(安全角色引用)

如果企业 Bean 进行自己的安全检查,换句话说,如果它检查用户是否有权限执行任务,那么必须在此域中提供安全角色引用(消息驱动 Bean 无需安全角色,因为它仅仅是在消息中传播来自客户端的任何安全信息。任何所需的安全检查都是在此之后进行的:可能是由容器,或者是消息驱动 Bean 请求工作的企业 Bean 完成)。

为了使用该域,您必须在 Bean 类中提供相应的代码(编码安全,programmatic security)。例如,代码可能包含 javax.ejb.EJBContext 接口的方法:

isCallerInRole(rolename)

在这种情况下,您还要在属性页中增加所有可用的角色名,作为安全角色引用。

您也可以在模块级定义安全角色。更多的信息,请参考《构建 J2EE 应用》(Building J2EE Applications)

按下面的步骤,在 Bean 级上增加安全角色:

1. 点击 Security Role Reference(安全角色引用)域,然后点击省略号按钮。

出现 Security Role References 属性编辑器。

2. 点击 Add

出现 Add Security Role Reference 对话框。

3. 完成这些域。

  • Name(名称): 安全角色名称,将出现在 Bean 的代码中。必填项。
  • Description(描述): 关于角色的解释。可选项。
  • Security Role Link.(安全角色连接): 部署环境中,与安全角色的连接(在 Bean 级上,此域是可选的。直到部署时,此域的数据才有用。此域通常由部署者完成)。

使用 J2EE RI 标签面板

J2EE 参考实现标签面板显示的属性,是您使用 EJB Builder 创建企业Bean 时自动分配的。这些属性包含了适合部署及测试 Bean 的默认值。当然,作为应用的一部份,在部署实体 Bean 之前,必须改变其中的一些值,一些空白域也必须填写。

如果您正在查看与 J2EE RI 相关的消息驱动 Bean、会话 Bean 或自己管理持久层的实体 BeanBMP)的属性,您将会发现只有很少的数据。然而,对于含有一个或多个 CMP Bean EJB 模块来说,就有大量的与J2EE RI 相关的属性。您可以看到 IDE 产生的指令,它们告诉容器如何将 Bean 与其底层的数据存贮对应起来。

首先,考虑对于单独的企业 Bean 而言,应该进入 J2EE RI 标签面板的那些属性域的值。然后,从创建 EJB 模块开始,我们将探讨如何使用企业 Bean, 创建 EJB 模块。之后,在 EJB 模块级上,为 CMP Bean 设置数据库相关的属性。

为单独的会话 Bean 和实体 Bean 设置属性

对于会话 BeanCMP Bean,以及 BMP Bean 而言,此标签面板显示 Client Authentication(客户端认证)、JNDI NameJNDI 名称)、Run As Specified User(以指定用户运行),以及 SSL RequiredSSL要求)属性。下面展示了一个命名为 ProcessOrder 的会话 Bean J2EE RI 属性标签面板。

Screenshot showing the J2EE RI tabbed pane of a session bean's property sheet.

如下设置这些域:

  • Client Authentication(客户端认证): 指定客户端是否通过口令进行认证(即,用户必须提供用户ID和口令),或者是证书(即,为了更高的安全性而使用公开密钥证书),或者是指定 Bean 必须让客户端自己选择口令或证书认证。
  • JNDI NameJNDI 名称): RI plugin 用默认值自动填写此域,在创建之前,JNDI lookup 方法使用此名称定位 Bean。您可以以修改该名称,但是不能为空。.
  • Run As Specified User(以指定用户运行):如果您希望 Bean 使用指定的安全身份,而不是调用者的安全身份,那么在此处指定用户的身份。如果您在 Security 对话框中选择了 Run-As Role(以角色运行),那么,您可以选择来自所选角色的用户身份。
  • SSL RequiredSSL 要求): 默认值是 False。如果 Bean 需要安全套接口层协议,那么设置为 True

当部署 CMP 实体 Bean 到 RI 上时,您首先创建 EJB 模块,然后在 EJB 模块层上处理它与其底层数据存贮的关系。更多的信息,请参考 设置 CMP 实体 Bean 的数据库相关属性

设置消息驱动 Bean J2EE RI 属性

消息驱动 Bean J2EE RI 标签面板同样也包含一些域,这些域描述了 Bean 可以使用的消息类型。

Screenshot showing the J2EE RI tabbed pane of a message-driven bean's property sheet.

如下设置这些域:

  • Client Authentication(客户端认证):.如同其它类型的 Bean 一样,此处指定客户端是否通过口令、证书来认证,或者是由客户端提供认证手段。
  • Connection Factory Name(连接工厂名称): 指定名称,通过该名称,来定位消息驱动 Bean 的队列或主题连接工厂。
  • Destination JNDI Name(接收者 JNDI 名称): 指定名称,通过该名称,来定位消息驱动 Bean 的队列或主题。
  • Durable Subscription Name(持久订阅名称): 如果消息驱动 Bean 订阅了一个主题,并且是持久订阅,那么在此处指定名称。
  • Run As Specified User(以指定角色运行): 如果消息驱动 Bean 使用特定的安全身份,则在此处指定身份。否则,Bean 将使用调用者的身份。
  • SSL RequiredSSL 要求):默认值是 False。如果 Bean 需要安全套接口层协议,那么设置为 True

为了设置 CMP Bean 的数据库相关的属性,首先必须已经存在一个 EJB 模块,或者创建一个。下面将论述 EJB 模块。


创建 EJB 模块

或许您已经设计过独立工作企业 Bean,或许您已设计过几个协同工作的企业 Bean。不论哪种情况,您可能都希望将企业 Bean 打包进 EJB 模块中,使得恰当的 Bean ,以及有关这些 Bean 的运行环境的所有必须的信息,都封装为一个整体。

只要企业 Bean 位于相同的 JVM 中,无论它们是否处于同一个模块中,它们都可以协同工作。然而,有时候将相互协作的 Bean 放入相同的模块中可以带来一些便利性。

IDE 中,EJB 模块是逻辑实体。它是其物理实体——EJB JARJava归档文件,扩展名.jar)的符号表示。EJB 模块记录了需要放入 EJB JAR 中的 Bean 的清单,以及 Bean 与它们的属性的连接。这些属性需要在部署环境中设置。EJB 模块是可以部署到应用服务器的企业 Bean 的最小单元。

正如您在 IDE Explorer 窗口所看到的,EJB 模块节点也代表了该模块的部署描述符。它列出了组成模块的企业 Bean,以及从何处载入 Bean 的源代码的说明。EJB 模块中的 Bean 可以位于相同的目录,或者位于不同的目录,甚至是不同的文件系统。实际上,Bean 本身或它们的拷贝都不在 EJB 模块之中。

决定将哪些内容放入 EJB 模块中

一些通用的准则可以帮助我们决定将多少企业 Bean 打包为一个单独的 EJB 模块(详细信息请参考 Java 2 平台,企业版文档)。您可能会为下面任何一个目的,打包企业 Bean

  • 最大可复用性:如果企业 Bean 是高度可复用的,您应该将它打包为一个单独的 EJB 模块。当装配应用时,该模块可自由地与其它模块组合,只提供应用所需的功能,减少应用的大小。

您应该将那些极大可能在一起使用的 Bean 组成一个模块。例如,所有在 EJB 2.0 环境中构建的 CMP Bean 以及相互之间存在关系的 CMP Bean,必须放在同一个模块中。

  • 最大易装配性: 如果您将应用所需的所有企业 Bean,或者至少是应用的一个模块中的所有 Bean,打包为一个模块,应用装配者就只需做少许工作。如果不存在可复用性问题,这是个行之有效的方法。
  • 在可复用性和易装配性中权衡: 对于中等大小的 J2EE 应用,您或许可以将任何有关联的,或者是紧密耦合的企业 Bean 打包为一个模块;任何独立的、可复用的 Bean,每个打包为独立的模块。按关联的功能、相互的依赖性、循环引用或共同的安全特征,对 Bean 进行分组,是个不错的方针。

将企业 Bean 放入 EJB 模块中

按下面的步骤,建立包含一个企业 Bean EJB 模块:

1. Explorer 窗口,鼠标右键点击 Bean 的逻辑节点,选择 Create New EJB Module(创建新 EJB 模块)。

2. New EJB Module 对话框中, 重命名模块(如果需要的话)。

3. 从文件系统的树型视图中选择模块的位置。

4. 点击 OK

按上面的步骤,创建含有多个协作的企业 Bean EJB 模块。不同的是,您要使用 Control 键或 Shift 键,同时选择所有您想放入同一个模块的企业 Bean

另一个方法是,鼠标右键点击 Bean Java 包,然后选择 New right arrow J2EE right arrow EJB ModuleIDE 将在此包中新建一个空的 EJB 模块。点击模块节点,选择 Add EJB(添加 EJB)。在出现的文件选择窗口中,使用 Control 键或 Shift 键,选择所有您想添加的 Bean

Explorer 中,展开模块节点,查看模块的内容。

Screenshot showing an expanded EJB module and the beans it contains, as shown in the Explorer.

如果您需要将多个一起工作的 CMP Bean 放入一个 EJB 模块中,那么,最好是从使用 EJB Builder 向导,从数据库或数据模式创建相互关联的 CMP Bean 着手。(在创建 CMP 的)同时,向导围绕这些 CMP,创建 EJB 模块。如果您按这种方式进行,IDE 将自动维护 Bean 之间的关系。

当然,如果您需要向已创建好的 EJB 模块中添加企业 Bean,您可以按下面的步骤来做:

1. Explorer 窗口中,鼠标右键点击 EJB 模块节点,选择 Add EJB

出现文件选择窗口,显示文件系统树型视图。

2. 从树型视图选择企业 Bean

3. 点击 OK

设置 CMP 实体 Bean 的数据库相关属性

CMP 实体 Bean RI 相关的属性是在 EJB 模块级上提供的。图8-2展示了名为 EJBModule_AccountsSouth EJB 模块的 J2EE RI 标签面板。稍后,您将看到这个 EJB 模块包含了几个关系 CMP Bean。注意,此面板中的域标明了 Bean 与底层数据存贮的关系,以及容器在管理它们之间的关系中所扮演的角色。

 图 8-2 含有 CMP EJB 模块的 J2EE RI 标签面板展示属性

Screenshot showing the J2EE RI tabbed pane of an EJB module.


注意——如果您打算对 CMP Bean 使用 IDE 的测试特性,您可能需要等待,直到稍后创建了该 CMP Bean 的 EJB 模块。测试过程会创建一个 EJB 模块。它只是一个让您测试 CMP Bean 代码和所有部署设置的模块,不能部署于生产环境。按照本节的说明,通过测试过程,运行 CMP Bean,发现您所设置的属性是如何工作的,然后将这些设置复制到生产环境下使用的“真实的”EJB 模块,从而节省时间。有关测试企业 Bean 的信息,请参看第9章


对于所有的 CMP Bean,完成以下的域:

  • Data Source JNDI Name(数据源 JNDI 名称): 实体 Bean 状态更新的数据存贮的 JNDI 名称。例如,jdbc\Pointbase,其中 jdbc 表示数据存贮的类型, Pointbase 表示特定的数据存贮。
  • Data Source Password(数据源口令): 访问数据库所需的口令。
  • Data Source UserName(数据源用户名): 访问数据库所需的用户名。

注意——如果您使用 IDE 内置的 PointBase 数据库服务器,那么,键入上面所示的 JNDI 名称,仅首字母大写。默认的用户 ID 和口令是相同的:pbpublic(记住,在键入口令后,按 Enter 或 Return 键)。


根据您创建 CMP Bean Bean 的方式,以及您是否希望 CMP Bean 使用已有的数据库表,您必须采用不同的方式来处理剩下的 RI 相关的属性。

理解 RI 产生的 SQL

当您使用 EJB Builder 向导创建 CMP Bean,并且 Automatically Generate SQL 域设置为默认值 True时,J2EE RI Plugin 将提供 SQL 语句,它需要此 SQL 语句来管理与 Bean 关联的底层数据库的持久层记录。Plugin 使用 Bean 的方法和域(即属性),以及您为某些方法提供的任何 EJB QL 代码,产生明确的 SQL 代码,供服务器使用。对于所有在 IDE 中安装的服务器,这一点都是正确的:每个服务器使用 Bean 的代码和 EJB QL,产生它自己的服务器特定的 SQL

无论何时添加 CMP 域、删除 CMP 域、修改组成主键的域,或者改变容器管理的关系,Plugin 都可以重新产生 SQL 语句。当然,您可以选择是否使用 SQL 重新产生特性。如果您使用这个特性,即,设置此域的值为 True,您就不能编辑 SQL 语句,除非 EJB 模块包含了1.1版本的 CMP Bean(在这种情况下,参看如果 EJB 模块中包含 EJB 1.1 CMP 实体 Bean,看看需要修改哪个语句)。

产生的语句是设计来做以下工作的:

  • 在部署 Bean 时,创建表。表被命名为 BeanTable (其中,Bean CMP Bean 的名称)。表中的列是按相应的 CMP 域来命名的。
  • 卸载Bean 时,删除表。
  • Bean 执行过程中,删除、插入及更新记录。

下面介绍设置 CMP Bean 的数据库相关的属性的一些准则。

如果 CMP Bean 无需使用已有的数据库表

或许 CMP Bean 并不需要使用已有的数据库表,并且您希望 RI Plugin 创建新表,比如在测试过程中。在这种情况下,您不用修改 Automatically Generate SQL(自动产生 SQL)域和 Use Delimited Identifiers in SQL(使用界定标识)域,使用它们的默认值就可以了。


注意——当且仅当您确信 Bean 名称、CMP 域名称、以及 CMR 域名称是数据源所指定的 SQL 数据库的保留字时,关闭界定标识。


SQL Generation TargetSQL 产生目标)中使用默认设置,或指定其它数据库。

点击 SQL Deployment Settings(SQL 部署设置)域,然后点击省略号按钮,查看创建和删除表的默认设置。出现 SQL Deployment Settings 属性编辑器,如图8-3所示。

  8-3 EJB 模块中 CMP 实体 Bean 的关联表设置示例

Screenshot showing the SQL Deployment Settings property editor with one of the EJB module's beans selected and expanded.

注意,当选择了 Bean 节点,就将出现关联表设置。

在属性编辑器中,展开 Bean 节点,选择其中一个方法,查看 RI Plugin CMP Bean 产生的默认的 SQL 语句。如图8-4所示的例子,展示了方法的 SQL 语句。

  8-4 RI Plugin CMP Bean createTable 方法产生的 SQL 语句的示例

Screenshot showing the SQL Deployment Settings property editor with one of the EJB module's bean nodes expanded and one of that bean's methods selected.

您应该使用服务器产生的 SQL 语句,除非 EJB 模块含有 1.x 版本的 CMP Bean。在这种情况下,参看如果 EJB 模块中包含 EJB 1.1 CMP 实体 Bean


caution icon

警告——IDE 不会阻止您在 Bean 的属性页修改已产生的 SQL 语句。然而,只要可能,您应该通过 Bean 的 EJB QL 语句,而不是属性页来修改。这样,您所使用的任何应用服务器的 Plugin 都可以自动传播您所做的改变。Bean 的服务器特定的 SQL 代码是需要产生的。您对产生的 SQL 代码的修改,可能会丟失。


如果 CMP Beans 需要使用已有的数据库表

如果 CMP Bean需要使用已有的数据库表(比如,您从表中产生 Bean 的基础结构,以及您希望使用该表来测试),使用以下的设置:

Automatically Generate SQL

True (默认值)

SQL Generation Target

(包含表的数据库。该数据库必须是数据源 JNDI 名称所映射的那个数据库)。

Use Delimited Identifiers in SQL

False

Automatically Generate SQL True 意味着当您改变 CMP Bean 的持久域和容器管理的关系时,RI Plugin自动重新产生 SQL 语句,并且一直更新(下一节,将谈到此规则的一个例外)。


注意——确保 Bean(表)或 Bean 的域(列)的名称没有使用 SQL 的保留字。


点击 SQL Deployment Settings 域,并点击省略号按钮。在出现的属性编辑器中,选择每一个您希望依靠已有的表来进行测试的 CMP Bean。为每一个所选择的 Bean,取消 Create Table on Deploy(部署时创建表)和 Delete Table on Undeploy(卸载时删除表)复选框的设定。取消设定意味着 RI Plugin 不会为 Bean 创建任何表,供其使用,也不会在应用不再运行时,删除任何表。

同样,您无须调整产生的 SQL 语句,除非 EJB 模块中含有 EJB 1.1 CMP Bean

如果 EJB 模块中包含 EJB 1.1 CMP 实体 Bean

在一个应用中,可能包含一个或多个使用早期的 Sun Java System Studio IDE、依据之前的 EJB 规范产生的 CMP 实体 Bean。或者,应用中的某个 CMP Bean 可能基于 1.x 版本的 Bean(创建这样一个 CMP Bean 的详细信息,请参看)。如果是这样,您可以如同处理 EJB 2.0 CMP Bean 一样处理这些 CMP Bean,但是必须做一个重要的改动。您必须调出产生的 SQL 语句,调整 finder 方法的 WHERE 子句。

打开 EJB 模块的属性页 -> J2EE RI 标签面板 -> SQL Deployment Settings 域,进行编辑。点击该域,然后点击省略号按钮,出现 SQL Deployment Settings 属性编辑器。

按下面的步骤,编辑 WHERE 子句:

1. 找到 EJB 1.1 CMP Bean 节点,并展开。

2. 选择 Bean finder 方法的节点。

您将看到类似于 图 8-5 所示的 SQL 语句。

  8-5 CMP Bean Finder 方法的 SQL 语句示例

Screenshot of the SQL Deployment Settings property editor with an EJB module's bean nodes expanded and the bean's Find By Primary Key method selected.

3. 完成 WHERE 子句。

  • 对于 FindByPrimaryKey 方法,如果未使用 Plugin 产生的 SQL,您可以修改列名。否则,保持方法的原样,不做修改。
  • 对于其它的 finder 方法,您必须提供约束。例如,命名为 findByY2000Accounts finder 方法可能是如下形式:findInCustIDRange(double low, double high)。在这种情况下,SQL 语句可能是下面的形式: SELECT "custID" FROM "CustomerTbl" WHERE "custID" > ?2000 AND "custID" < ?2001 。问号后面的数字表示了 finder 方法参数表中的相应参数。

RI Plugin 重新产生 SQL 语句时,您对 WHERE 子句所做的修改是受保护的,不会丟失。

关于在当前 IDE 版本处理 EJB 1.1 CMP 实体 Bean 的更详细的信息,请参看附录 B

理解 CMP 域值的顺序

如果您有可能修改 RI Plugin CMP 产生的SQL,您就需要理解 CMP 域是如何排序的。

容器是按字母顺序,向数据库发送 CMP 域的值。如果表的列名与 CMP 域名不同,您就必须按照数据列所映射的域的字母顺序来组织(SQL 语句中)表的列。例如,假设 CMP Bean 类命名为EmployeeEJB

  • 源数据库表命名为 Employee
  • CMP 域命名为 addresscityid name
  • 映射的表的列命名为 Mail_AddressCityEmp_ID Emp_Name
  • INSERT 语句默认产生的SQL 语句如下:

    INSERT INTO "EmployeeEJBTable" ("address", "city", "id", "name") VALUES (?, ?, ?, ?)

    在这个例子中,您需要按下面的代码,修改 SQL

    INSERT INTO "Employee" ("Mail_Address", "City", "Emp_ID", "Emp_Name") VALUES (?, ?, ?, ?)

    表的列名是按与映射的 CMP 域相同的字母顺序来排列的(而不是表的列的字母顺序)。这是由于 VALUES 参数是按 CMP 域的字母顺序来传送的。

添加 EJB 模块的事务属性

事务属性通知 EJB 容器如何控制 CMT Bean 的事务。对于自己管理事务的会话 BeanBMT Bean),您必须明确地编写 Bean 的事务处理代码。对 CMT Bean,您无须明确地编码。相反,容器根据您分配给 Bean 方法的事务属性来控制事务。

默认情况下,IDE 设置所有的 Bean 方法使用 Required 属性。您可以在Bean 级或方法级上分配不同的事务属性。例如,如果您不希望某个特定的方法包含在事务上下文中,您可以将该方法的事务属性由 Required 改为 Not Supported

事务属性保存于部署描述符中,可以通过 EJB 模块的属性页编辑。在将包含 CMT Bean EJB 模块装配进应用之前,必须确保已经为该模块指定了相应的事务属性。

当您改变了单独一个 Bean Bean 的某个方法的事务属性,您所做的改变仅仅限于该 EJB 模块的执行。Bean 的源代码不会被改变的。如果您在其它 EJB 模块中复用这个 Bean,您可以提供不同的事务属性:

按下面的步骤,改变 CMT Bean 的事务属性:

1. Explorer 窗口中,鼠标右键点击 Bean 所在的 EJB 模块,选择Properties

Properties 标签面板中,注意到 Transaction Settings 域显示的值是 Container-transaction(容器管理的事务)

2. Properties 标签面板中,点击 Container-transaction ,,然后点击省略号按钮。

出现 Transaction Settings 对话框。注意,较大的面板中显示了模块的企业 Bean 使用 CMT,每个 Bean 都有事务属性,这是为整个 Bean 设置的。

Screenshot showing the Transaction Settings dialog box for an EJB module.

  • 选择 Bean,然后在事务属性组合框中选择其它项,改变 Bean 的事务属性。新属性将出现在较大窗口中的该 Bean 名称的旁边。
  • 要改变特定方法的事务属性,展开 Bean,选择方法,然后在事务属性组合框中选择其它项。如下面所示,新的属性出现在较大窗口中该方法名的旁边。注意,Bean 的其它方法没有显示事务属性,除非重置了默认的属性。

Screenshot showing a particular example method selected with its transaction attribute and description.  

当在 Transaction Settings 对话框中进行设置时,您可以向应用装配者提供模块中每个 Bean 或其方法的事务设置的描述。例如,您可能需要解释为什么您修改了当前 EJB 模块中特定的事务属性。

3. 完成事务属性的修改后,点击 OK

EJB 模块或应用中改变 EJB 引用

指定 EJB 本地引用指定 EJB 引用两节中,您已看到如何在单独的 Bean 级上声明企业 Bean 之间的引用。 这些引用可以按下面的步骤来重置:

  • 如果 Bean 在相同的 EJB 模块中,您可以在 EJB 模块级上重置引用;
  • 如果 Bean 在不同的 EJB 模块中,但处于同一个应用中,您可以在应用级上重置引用。

在某些情况下,该特性是很方便的。比如,您希望将一个特定的企业 Bean 打包进三个不同的 EJB 模块,而这三个模块被一个或多个应用使用,并且用法各不相同。

要使用这个特性,您必须为 EJB 模块(或应用)提供两个或多个接口相同的企业 Bean。该特性可用于 localremote,或 local remote 接口,但是 Bean 的接口必须是相同的,而 Bean 类或属性(部署信息)可以是不同的。

在模块级上重置引用

按下面的步骤,重置 EJB 模块中的 Bean 引用:

1. Explorer 窗口中,鼠标右键点击包含 Bean EJB 模块,并选择 Properties

2. 点击可用的引用域(EJB Local References EJB References),然后点击省略号按钮。

出现相应的属性编辑器。

3. 找到您想重置引用的企业 Bean,点击 Override 复选框。

4. 点击 Override Value(重置值)域。

在 Override Value 域之下,出现包含您可选择的企业 Bean 名称的组合框。如图 8-6所示。

  8-6 EJB Local References Property EditorEJB 本地引用属性编辑器), 展示了企业 Bean 本地引用重置选择的示例

Screenshot showing the EJB Local References property editor for an EJB module.

5. 选择您希望 Bean 使用的引用,然后点击 OK

在应用级上重置引用

按下面的步骤,在应用级上重置 Bean 引用:

1. Explorer 窗口中,鼠标右键点击包含 Bean 的应用,然后选择Properties

2. 点击可用的引用域(EJB Local References EJB References),然后点击省略号按钮。

出现相应的属性编辑器。

在模块级和应用级上,EJB references EJB local references 的属性编辑器是相同的。按上一节所述,继续相同步骤。

创建 EJB JAR

创建完 EJB 模块之后,如果您要将该模块递交给组织中的其它部门或者小组,以便装配应用,那么,您可能需要创建一个 EJB JAR 文件。在应用中,可使用该文件来输出模块及其内容。按下面的步骤,创建 EJB JAR 文件:

1. Explorer 窗口中,选择 EJB 模块。

2. 点击鼠标右键,选择 Export EJB JAR File(输出 EJB JAR 文件)。

出现 Output Window(输出窗口),在编译模块及其内容过程中,显示进度。请注意在此窗口中出现的任何错误信息。

EJB JAR 文件创建后,您仍然可以为在该 EJB JAR 文件中使用,或者是为在其它 EJB JAR 文件中使用,调整模块或其内容。

一个或多个 EJB模块可以放入一个 J2EE 应用中,并部署。关于装配和部署的详细信息,请参考《构建 J2EE 应用》Building J2EE Applications)。

EJB 模块中添加 JAR 文件

您可能需要 EJB 模块中的企业 Bean 利用另一个容器中的 Bean 所提供的功能。例如,如果有一个会话 Bean 需要认证用户,您就可以添加一个包含了实现安全检查的 Bean JAR 文件。按下面的步骤,向 EJB 模块中添加已有的 JAR 文件:

1. Explorer 的文件系统面板中,装配(mount)包含 JAR 文件的文件系统。

2. 鼠标右键点击 EJB 模块节点,选择 Properties

3. 在模块的属性页中,点击 Extra Files(外部文件)域,然后点击省略号按钮。

4. Source 面板中,定位要添加的 JAR 文件,选择该文件,然后点击 Add

JAR 文件出现在 Files To Be Added(要添加的文件)面板中。

5. 点击 OK,添加该 JAR 文件。

当您部署 EJB 模块时,此 JAR 文件是包含在模块的 EJB JAR 文件中的。

创建EJB组件

816-7864-10

Table of Contents Table of Contents Next Chapter