EJB 3.0 应用程序绑定概述

来源:互联网 发布:数据库系统原理答案 编辑:程序博客网 时间:2024/06/08 06:01

http://pic.dhe.ibm.com/infocenter/wasinfo/v6r1/index.jsp?topic=%2Fcom.ibm.websphere.ejbfep.multiplatform.doc%2Finfo%2Fae%2Fae%2Fcejb_bindingsejbfp.html

EJB 3.0 应用程序绑定概述

将应用程序安装在应用程序服务器上后,必须将该应用程序中定义的所有 Enterprise JavaBeans(EJB)引用和资源引用都绑定至应用程序服务器上定义的实际工件(企业 bean 或资源),然后才能启动该应用程序。

当定义绑定时,请在应用程序中为可引用对象和已引用工件指定 Java 命名和目录接口(JNDI)名称。对工件指定的 jndiName 值必须是限定的查询名。

不需要手动为 EJB 3.0 模块中企业 bean 上的各个接口或 EJB home 接口指定 JNDI 绑定名称。如果未显式地指定绑定,那么 EJB 容器将指定缺省绑定。

对于 Feature Pack for EJB 3.0,WebSphere 产品为 EJB 接口提供了两个不同的名称空间,取决于接口是本地还是远程接口。此配置适用于 EJB home 接口,此类接口被视为特殊类型的接口。这两个名称空间如下所示:
  • JVM 作用域的 ejblocal: 名称空间
  • 全局 JNDI 名称空间

本地 EJB 接口和 home 接口必须始终绑定至 JVM 作用域的 ejblocal: 名称空间;只能从同一应用程序服务器进程中访问这些接口。

相反,远程 EJB 接口和 home 接口必须始终绑定至全局作用域的 WebSphere JNDI 名称空间;可从任何位置(包括其他服务器进程和其他远程客户机)访问这些接口。本地接口无法绑定至全局作用域的 JNDI 名称空间,而远程接口无法绑定至 JVM 作用域的 ejblocal: 名称空间。

ejblocal: 和全局作用域的 JNDI 名称空间之间完全独立且截然不同。例如,绑定在“ejblocal:AccountHome”上的 EJB 本地接口与绑定在全局作用域中“AccountHome”上的远程接口完全不同。这有助于区别本地和远程接口引用。由于具有 JVM 作用域的局部名称空间,因此应用程序也可以直接从 JVM 服务器进程中的任何位置(包括跨 Java Platform, Enterprise Edition(Java EE)应用程序边界)查询或引用本地 EJB 接口。

EJB 3.0 容器根据应用程序、模块和组件名称指定 EJB 业务接口的缺省 JNDI 绑定

由于功能部件包的 EJB 容器根据应用程序名称、模块名和组件名称指定 EJB 业务接口的缺省 JNDI 绑定,因此必须了解这些名称是如何定义的。这些名称均为一个字符串。

Java EE 应用程序以称为企业应用程序归档(EAR)的标准化格式进行封装。EAR 是一种类似于 .zip 或 .tar 文件格式的封装文件格式,因此可形象地认为 EAR 是一组被同时封装在单个物理文件中的逻辑目录和文件。每个 EAR 文件均含有一个或多个 Java EE“模块”文件,其中包括:
  • EJB 模块、Java EE 应用程序客户机模块和实用程序类模块的 Java 应用程序归档(JAR)文件
  • Web 模块的 Web 应用程序归档(WAR)文件
  • 其他特定于技术的模块(例如资源应用程序归档(RAR)文件)以及其他类型的模块
每个模块文件通常均含有一个或多个 Java EE 组件。例如,Java EE 组件可以是企业 bean、servlet 和应用程序客户机主类。

由于 Java EE 模块封装在 Java EE 应用程序归档中,而 Java EE 组件又封装在 Java EE 模块中,因此可根据每个组件的“嵌套路径”中的应用程序名称、模块名和组件名称来唯一地标识 Java EE 应用程序归档中的每个组件。

应用程序名称

应用程序的名称由以下各项(按优先级排序)定义:
  • 将应用程序安装到 WebSphere Application Server 期间,指定给 WebSphere Application Server 管理控制台的“应用程序名称”值,或者提供给 wsadmin 命令行脚本工具的“appname”参数值。
  • 应用程序的 META-INF/application.xml 部署描述符中 <display-name> 参数的值。
  • EAR 文件名,不包括其“.ear”文件后缀。例如,名为 CustomerServiceApp.ear 的应用程序 EAR 文件在这种情况下将使用“CustomerServiceApp”作为应用程序名称。

模块名

模块的名称定义为模块文件的统一资源标识(URI),该 URI 相对于 EAR 文件根目录。换句话说,模块名是相对于 EAR 文件根目录的模块文件名,其中包括任何嵌套了该模块文件的“子目录”。

在以下示例中,CustomerServiceApp 应用程序包含三个模块,其名称分别为 AccountProcessing.jar、Utility/FinanceUtils.jar 和 AppPresentation.war:
CustomerServiceApp.ear:   AccountProcessing.jar     com/             mycompany/           AccountProcessingServiceBean.class           AccountProcessingService.class   Utility/     FinanceUtils.jar       META-INF/         ejb-jar.xml     com/         mycompany/           InterestCalculatorServiceBean.class           InterestCalculatorService.class   AppPresentation.war     META-INF/       web.xml

EJB 组件名称

EJB 组件的名称由以下各项(按优先级排序)定义:
  • ejb-jar.xml 部署描述符中与 bean 相关联的 ejb-name 标记(如果存在)的值。
  • 与 bean 相关联的 @Stateless 或 @Stateful 注释中“name”参数(如果存在)的值。
  • bean 实现类的名称,不带任何包级别限定符。

绑定

请查看 EJB 3.0 支持的如下绑定:

  • 业务接口和 home 接口的缺省绑定
  • 缺省绑定模式
  • EJB 业务接口和 home 接口的用户定义绑定
  • 用于对引用和注入目标进行解析的用户定义绑定
  • EJB 引用和 EJB 注入的缺省解析
  • 集群环境中的命名注意事项
  • 旧的(XMI)绑定
  • 用户指定的 XML 绑定

业务接口和 home 接口的缺省绑定

Feature Pack for EJB 3.0 中,没有必要为您的每个接口或 EJB home 接口都显式地定义 JNDI 绑定名称。如果未显式地指定绑定,那么 WebSphere 的 EJB 容器将使用此处所述的规则来指定缺省绑定。这与 WebSphere 产品中该功能部件包之前的 EJB 支持稍有不同。

该容器为每个企业 bean 上的各个接口(业务接口、远程 home 接口或本地 home 接口)执行两个缺省绑定。这两个绑定在此处被称为接口的“短格式”绑定和“长格式”绑定。短格式绑定只使用接口的包限定 Java 类名,而长格式绑定使用企业 bean 的组件标识作为包限定接口类名的附加限定符,并使用破折号或编号符号(符号 #)来隔开组件标识和接口类名。可将这两种格式之间的差别设想为类似于“短格式”TCP/IP 主机名(仅机器名称)与“长格式”主机名(前面加了域名的机器名称)之间的差别。

例如,接口的短格式缺省绑定和长格式缺省绑定可能分别为“com.mycompany.AccountService”和“AccountApp/module1.jar/ServiceBean#com.mycompany.AccountService”。

缺省情况下,EJB 缺省绑定的组件标识是使用企业 bean 的应用程序名称、模块名和组件名称(如上定义)构成,但您可以改为指定您所需要的任何字符串。通过将您自己的字符串定义为组件标识,您可以建立命名约定,其中,企业 bean 的长格式绑定共用一个公共的用户定义部分,而且还具有一个系统定义的部分(基于每个接口类的名称)。此外,它还允许您使缺省 EJB 绑定名称独立于在应用程序/模块层次结构中对企业 bean 进行封装的方式。在本主题的“EJB 业务接口和 home 接口的用户定义绑定”部分中描述了有关覆盖企业 bean 的缺省组件标识的内容。

如先前在 JVM 作用域局部名称空间和全局作用域 JNDI 名称空间部分中所提及的那样,所有本地接口和 home 接口都必须绑定至只能从同一服务器进程(JVM)访问的 ejblocal: 名称空间,而远程接口和 home 接口都必须绑定至可从 WebSphere 产品单元中的任何位置访问的全局作用域名称空间。如您所愿,对于缺省绑定来说,EJB 容器遵循这些规则。

此外,远程接口的“长格式”缺省绑定还遵循建议的 Java EE 最佳实践,以一个 ejb 上下文名称进行分组。缺省情况下,EJB 远程 home 接口和业务接口都绑定至应用程序服务器命名上下文的根。但是,应用程序服务器根上下文不只是用于绑定 EJB 接口,因此,为了避免此上下文太混乱,最佳实践是将与 EJB 相关的绑定分组到公共“EJB”子上下文,而不是将其直接放置在服务器根上下文中。这样做的原因类似于使用磁盘卷上的子目录,而不是将所有文件都放入根目录中。

远程接口的短格式缺省绑定不会绑定至 ejb 上下文。短格式缺省绑定位于服务器根上下文的根目录中。即使最佳实践是将所有与 EJB 相关的绑定分组到 ejb 上下文,但需要考虑其他事项,其中包括以下各项:
  • 短格式缺省绑定提供了简单而直接的方法来访问 EJB 接口。如果将这些绑定直接放在服务器根上下文中,并仅通过接口名称或前面添加了 ejblocal: 的接口名称来引用这些绑定,那么将有助于遵循简洁这一目标。
  • 同时,将长格式缺省绑定放入 ejb 上下文或者放入 ejblocal: 上下文(如果是本地接口)时,为尽量减少混乱,请不要将这些绑定放入服务器根上下文中,从而允许根上下文中具有短格式绑定。
  • 它提供了与其他使用类似命名约定的 Java EE 应用程序服务器的一定程度的跨兼容性。

总之,所有本地缺省绑定,格式不论长短,均被放入 ejblocal: 服务器/JVM 作用域名称空间中,而对于远程缺省绑定而言,如果为短格式,就被放入全局作用域的名称空间中,否则被放入 <server_root>/ejb 上下文中(在紧随服务器根上下文的下面)。因此,服务器的全局作用域根上下文中的仅有缺省绑定是远程接口的短格式绑定,这可以确保在以下两个方面取得最佳均衡:提供一个可移植的简单用法模型;避免使服务器的全局作用域根上下文变得太混乱。

缺省绑定模式

表中显示了每种绑定的模式。在这些模式中,用 <bracketed italics> 编写的字符串表示一个值。例如,<package.qualified.interface> 可以是类似于 com.mycompany.AccountService 的内容,而<component-id> 可以是类似于 AccountApp/module1.jar/ServiceBean 的内容。
描述绑定模式短格式本地接口和 home 接口ejblocal:<package.qualified.interface>短格式远程接口和 home 接口<package.qualified.interface>长格式本地接口和 home 接口ejblocal:<component-id>#<package.qualified.interface>长格式远程接口和 home 接口ejb/<component-id>#<package.qualified.interface>
component-id 缺省为 <application-name>/<module-jar-name>/<ejb-name>,除非在 EJB 模块绑定文件中使用 component-id 属性将其覆盖,如下一部分“多个企业 bean 实现同一接口时短格式缺省绑定名称中的冲突”中所述。

多个企业 bean 实现同一接口时短格式缺省绑定名称中的冲突

如果在应用程序服务器中运行的多个企业 bean 实现给定接口,那么由于短格式缺省绑定名称可能表示任何实现此接口的 Enterprise JavaBeans,因此该短名称将变得很含糊。为了避免这种情况,您必须显式地为实现给定接口的每个 Enterprise JavaBeans 分别定义一个绑定(如下一部分所述),或者通过定义 WebSphere 产品“JVM 定制属性”com.ibm.websphere.ejbcontainer.disableShortDefaultBindings 来禁用包含这些 Enterprise JavaBeans 的应用程序的短格式缺省绑定。有关定义 JVM 定制属性的更多信息,请参阅“Java 虚拟机定制属性”主题。

要使用此 JVM 定制属性,请将属性名称设置为 com.ibm.websphere.ejbcontainer.disableShortFormBinding,并且将属性值设置为 *(星号)通配符值以禁用服务器中所有应用程序的短格式缺省绑定,或设置为用冒号分隔的 Java EE 应用程序名称序列(您要禁用这些应用程序的短格式缺省绑定,例如 PayablesApp:InventoryApp:AccountServicesApp)。

对缺省绑定进行显式指定的影响

如果显式地对某一接口或 home 接口指定绑定定义,那么不会对该接口执行任何短格式或长格式缺省绑定。
注: 这仅适用于您对其指定显式绑定的特定接口。该企业 bean 上其他没有显式指定绑定的实例都将使用缺省绑定名称进行绑定。

EJB 业务接口和 home 接口的用户定义绑定

如果要手动指定绑定位置,而不使用 WebSphere 产品缺省绑定,那么您可以使用 EJB 模块绑定文件将您自己的绑定位置指定给特定接口和 home 接口。也可以使用此文件仅覆盖模块中一个或多个企业 bean 上的缺省绑定的组件标识部分。如果覆盖组件标识,那么可以在允许绑定完全使用缺省值与完全指定每个接口的绑定名称之间提供一定的回旋余地。

要为 EJB 3.0 模块指定用户定义的绑定信息,请将名为 ibm-ejb-jar-bnd.xml 的文件放入 EJB JAR 模块的 META-INF 目录中。
注: 此文件的后缀为 XML,而非 XMI,这与 WebSphere Application Server 的先前版本一样。
另请注意,在定义本地接口的绑定时,必须在名称的前面加上字符串“ejblocal:”,以便它绑定至 JVM 作用域的 ejblocal: 名称空间。
ibm-ejb-jar-bnd.xml 文件适用于在 WebSphere Application Server 上运行的 EJB 3.0 模块,而 ibm-ejb-jar.bnd.xmi 文件适用于低于 EJB 3.0 的模块且适用于 Web 模块。基于以下原因,Feature Pack for EJB 3.0 在 ibm-ejb-jar.bnd.xml 中引入了新的绑定文件格式,而没有使用先前的 XMI 文件格式:
  • XMI 文件格式中声明的绑定和扩展取决于是否存在对应的 ejb-jar.xml 部署描述符文件,该文件显式地引用该文件中的元素所连接的唯一标识编号。此系统对于 EJB 3.0 模块已不再可行,在 EJB 3.0 中,不再要求模块包含 ejb-jar.xml 部署描述符。
  • XMI 文件格式设计为仅用 WebSphere Application Server 开发工具和系统管理功能进行机器编辑;实际上,它原先是 WebSphere 产品的内部实现的一部分,并且该文件的结构从未在外部加以记录。这使得开发者无法手动编辑绑定文件,也无法以受支持的方式创建绑定文件作为独立于 WebSphere 的构建过程。
  • 不是引用 ejb-jar.xml 部署描述符中的已编码标识编号,基于 XML 的绑定文件通过其 EJB 名称来引用 EJB 组件。模块中的每个 EJB 组件保证具有唯一的 EJB 名称(缺省值或由开发者显式指定的值),因此这提供了一种明确的方法来定位绑定和扩展。
  • 新的绑定文件都基于 XML;提供一个 XML 模式定义(xsd)文件以便在外部记录该结构。多种公共 XML 文件编辑器都可以使用这些 .xsd 文件来帮助执行语法验证和代码补全功能。因此,开发者现在可独立于 WebSphere Application Server 基础结构生成并编辑绑定和扩展文件。
下表列出了用于将绑定指定给 Feature Pack for EJB 3.0 中的 EJB 接口和 home 接口的 ibm-ejb-jar-bnd.xml 元素和属性。
元素或属性使用方法示例注释<session>为会话 bean 声明一组绑定指定。<session name="AccountServiceBean"/>需要 name 属性及下列其中的一项或多项:simple-binding-name 属性、local-home-binding-name 属性、remote-home-binding-name 属性或 <interface> 元素。name该属性标识 <session>、<message-driven>、<entity> 或其他元素所适用于的企业 bean 的 ejb-name。<session name="AccountServiceBean"/>ejb-name 值是在 ejb-jar.xml 部署描述符文件的 <ejb-name> 元素中声明的名称、@Session 或 @MessageDriven 注释的 name 参数或者缺省为使用 @Session 或 @MessageDriven 注释进行注释的 EJB 实现类的非限定类名(如果在 XML 部署描述符中未声明任何 <ejb-name> 值,并且未在注释上声明任何 name 参数)。component-id该属性覆盖企业 bean 的缺省组件标识值。此企业 bean 的缺省长格式绑定使用指定的组件标识取代<app_name>/<module_jar_name>/<bean_name>。<session name="AccountServiceBean" component-id="Dept549/AccountProcessor"/>
上述示例将生成一个 bean,它的 ejb-name 是 AccountServiceBean,它的长格式缺省本地接口被绑定至以下位置:
ejblocal:Department549/AccountProcessor#<package.qualified.interface>
它的长格式缺省远程接口被绑定至以下位置:
ejblocal:Department549/AccountProcessor#<package.qualified.interface>
可单独使用,或与 <interface> 元素、local-home-binding-name 属性或 remote-home-binding-name 属性一起使用。未对其指定显式绑定的接口将使用用户指定的组件标识值来执行缺省绑定。对其指定了显式绑定的接口将使用那些值进行绑定。

由于 simple-binding-name 属性适用于给定企业 bean 上的所有已定义接口(任何接口均不使用缺省值),因此通常没必要将 component-id 与 simple-binding-name 一起使用。

simple-binding-name一种简单机制,用于指定 Enterprise JavaBeans 的接口绑定以:
  • 实现单个 EJB 3.0 业务接口,或
  • 使用姊妹 EJB home 接口来实现低于 EJB 3.0 类型的组件接口(本地和/或远程类型)。
该属性的值用作为企业 bean 的业务接口的绑定位置,或用作为 Enterprise JavaBeans 本地和/或远程 home 接口的绑定位置。绑定被放入 ejblocal: 名称空间中(如果接口或 home 接口为本地),或者被放入全局作用域的 JNDI 名称空间的应用程序服务器根上下文中(如果接口或 home 接口为远程)。<session name="AccountServiceBean" simple-binding-name="ejb/AccountService"/>
此示例将生成一个 bean,它的 ejb-name 是 AccountServiceBean,它的本地业务接口或 home 接口(如果有的话)被绑定至局部 JVM 作用域的 EJB 名称空间中的以下位置:
ejblocal:ejb/AccountService 
它的远程业务接口或 home 接口(如果有的话)被绑定至全局作用域的 JNDI 名称空间的应用程序服务器根上下文中的以下位置:
ejb/AccountService
。必须注意此处使用了该属性(包括此特定示例中的该属性)的准确值(“ejb”子上下文名称),即使接口是被绑定至 ejblocal: 名称空间的本地接口亦如此。如果指定了用户定义的绑定,那么将使用该属性指定的准确名称。
不要将其与 local-home-binding-name 属性、remote-home-binding-name 属性或 <interface> 元素一起使用。另外,也不应该在实现多个业务接口的 bean 上使用(在这种情况下,请改用 <interface> 元素)。

如果在实现多个业务接口的企业 bean 上使用此属性,或者将业务接口和本地/远程组件接口与 home 接口一起使用,那么可通过如下方法来确保生成的绑定没有歧义:在属性值后面添加破折号或编号符号(# 符号),紧随其后是企业 bean 上每个接口和/或 home 接口的包限定类名。然而,可使用 <interface> 元素为每个业务接口定义绑定而不是使用 simple-binding-name 来避免这种情况。

要点:在 bean 上定义 simple-binding-name 以实现多个业务接口与使用 <component-id> 覆盖 bean 的缺省组件标识并不相同。使用 component-id 定义的远程接口缺省绑定仍分组到 ejb 上下文(所有远程接口缺省绑定都进行这样的分组),而远程接口绑定(这些绑定使用 EJB 容器来消除歧义,以便对在具有多个接口的 bean 上错误使用 simple-binding-name 的情况作出反应)并不被分组到 ejb 上下文。

另外,对于长格式缺省绑定,始终包含包限定类名,而对于 simple-binding-name,仅在发生错误时为消除歧义的情况下才包含包限定类名。如果依赖于通过消除歧义创建的绑定名称,就不是最佳实践,因为在更改 bean 以实现更多或更少接口时,可能会产生这样的影响。local-home-binding-name该属性用以指定企业 bean 的本地 home 接口的绑定位置。<session name="AccountServiceBean" local-home-binding-name="ejblocal:AccountService"/>不要将其与 simple-binding-name 属性一起使用。由于本地 home 接口必须始终绑定至 JVM 作用域的名称空间,因此该值必须始终以 ejblocal: 前缀开头。remote-home-binding-name该属性用以指定企业 bean 的远程 home 接口的绑定位置。<session name="AccountServiceBean" remote-home-binding-name="ejb/services/AccountService"/>不要将其与 simple-binding-name 属性一起使用。由于远程 home 接口无法绑定至 ejblocal: 名称空间,因此该值不能以 ejblocal: 前缀开头。<interface><session> 元素(将绑定指定给特定 EJB 业务接口)的子元素。与 simple-binding-name、local-home-binding-name 和 remote-home-binding-name 属性不同的是,binding-name 参数和类参数都是必需的(事实上,这种差别可解释需要单独的 XML 元素而不是某一属性的原因)。类参数指定要绑定的业务接口类的包限定名称。<interface class="com.ejbs.InventoryService" binding-name="ejb/Inventory"/>(声明为 <session> 元素中的一个子元素)不要将其与 simple-binding-name 属性一起使用。由于本地接口必须始终绑定至 JVM 作用域的名称空间,因此将此元素应用于本地接口时,binding-name 值必须始终以 ejblocal: 前缀开头。binding-name该属性用以指定使用 <interface> 元素进行绑定的业务接口的绑定位置。<interface class="com.ejbs.InventoryService" binding-name="ejb/Inventory"/>(声明为 <session> 元素中的一个子元素)必须与 <interface> 元素一起使用且仅在该元素上使用。由于本地接口必须始终绑定至 JVM 作用域的名称空间,因此在被应用于本地接口时,binding-name 值必须始终以 ejblocal: 前缀开头。

绑定文件示例 1

如下所示为一个简单的 ibm-ejb-jar-bnd.xml 文件,它仅包含将绑定名称指定给 EJB 接口的元素和属性。它覆盖用于企业 bean“S01”上的缺省绑定的组件标识,并对此模块中企业 bean“S02”和“S03”上的某些接口指定显式绑定。
<?xml version="1.0" encoding="UTF-8"?><ejb-jar-bndxmlns="http://websphere.ibm.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd" version "1.0">  <session name="S01" component-id="Department549/AccountProcessors"/>  <session name="S02" simple-binding-name="ejb/session/S02"/>  <session name="S03">  <interface class="com.ejbs.BankAccountService" binding-name="ejblocal:session/BAS"/>  </session></ejb-jar-bnd>
该绑定文件生成以下各项:
  1. 对 ejb-name 为“S01”的会话 bean 指定了一个用户定义的组件标识,该组件标识覆盖该 bean 上所有接口的缺省组件标识(应用程序名称/ejb-jar 模块名/bean 名称)。此 bean 上的本地接口被绑定至以下位置:
    ejblocal:Department549/AccountProcessors#<package.qualified.interface.name>
    而远程接口被绑定至以下位置:
     ejb/Department549/AccountProcessors#<package.qualified.interface.name>
  2. ejb-name 为“S02”的会话 bean 可假定具有单个 EJB 3.0 业务接口。另外,它可能还具有一个带本地 home 接口和/或远程 home 接口的低于 EJB 3.0 的“组件”接口。该业务接口或组件接口的 home 接口被绑定至以下位置:
    ejblocal:ejb/session/S02
    (如果是它是本地接口),或者被绑定至以下位置:
    ejb/session/S02
    (如果它是远程接口)。

    如果 bean S02 具有多个业务接口或多个业务接口和 home 接口,那么 simple-binding-name 就有歧义。在该情况下,此容器通过在该 bean 的各个接口的简单绑定名称 ejb/session/S02 后面添加 #<package.qualified.interface.name> 来消除绑定指定的歧义。

  3. ejb-name 为“S03”的会话 bean 上的 EJB 3.0 业务接口 com.ejbs.BankAccountService 被绑定至 ejblocal:session/BAS。
如果此 bean 上存在其他业务接口和 home 接口,那么对所有这些接口指定缺省绑定。在本示例中,由于为 ejblocal: 名称空间指定了 com.ejbs.BankAccountService,因此该接口可假定为本地接口;如果该接口不是本地接口,那么可能会发生错误。

下一部分将扩展此示例,引入一些元素,用于解析在 XML 部署描述符中或通过注释来声明的各种引用和注入条目的目标。

用于对引用和注入目标进行解析的用户定义绑定

前一部分说明了如何对业务接口和 home 接口指定用户定义的绑定名称。此部分说明如何解析引用、注入伪指令和消息驱动的 bean 目标的链接目标。

元素或属性使用方法示例注释<ejb-ref>解析 ejb-ref 声明的目标,该目标是通过 @EJB 注释或通过 ejb-jar.xml 部署描述符中的 ejb-ref 进行声明,在组件作用域的 java:comp/env 名称空间中声明的名称与 JVM 作用域的 ejblocal: 或全局作用域的 JNDI 名称空间中的目标企业 bean 的名称之间提供链接。<ejb-ref name="com.ejbs.BankAccountServiceBean/s02Ref" binding-name="ejb/session/S02"/>需要 name 和 binding-name 属性。<message-driven>为消息驱动的 bean 声明一组绑定指定。<message-driven name="EventRecorderBean"><jca-adapter activation-spec-binding-name="jms/InternalProviderSpec" destination-binding-name="jms/ServiceQueue"/></message-driven>需要 name 属性和 <jca-adapter> 子元素。<jca-adapter>定义 JCA 1.5 适配器激活规范和消息目标 JNDI 位置,用于将消息传递至消息驱动的 bean。<jca-adapter activation-spec-binding-name="jms/InternalProviderSpec" destination-binding-name="jms/ServiceQueue"/>需要 activation-spec-binding-name 和 destination-binding-name 属性。可根据情况包括 activation-spec-auth-alias 属性。<message-destination>将消息目标的名称(它是在 Java EE 模块部署描述符中定义的逻辑名称)与特定全局 JNDI 名称(它是 JNDI 名称空间中的实际名称)相关联。Java EE 模块部署描述符中的 <message-destination-ref> 元素,或者用于注入消息目标的 @Resource 注入伪指令随后可使用 <message-destination-line> 元素按目标逻辑名称来引用此 message-destination,而不需要绑定文件中每个已定义 message-destination-ref 的各个 <message-destination-ref> 绑定条目。<message-destination name="EventProcessingDestination" binding-name="jms/ServiceQueue"/>需要 name 和 binding-name 属性。<message-destination-ref>解析 message-destination-ref 声明的目标,该目标是通过 @Resource 注释或通过 ejb-jar.xml 中的 message-destination-ref 进行声明,在组件作用域的 java:comp/env 名称空间中声明的名称与全局 JNDI 名称空间中目标资源环境的名称之间提供链接。<message-destination-ref name="com.ejbs.BankAccountServiceBean/serviceQueue" binding-name="jms/ServiceQueue"/>需要 name 和 binding-name 属性。<resource-ref>解析 resource-ref 声明的目标,该目标是通过 @Resource 注释或通过 ejb-jar.xml 中的 resource-ref 进行声明,在组件作用域的 java:comp/env 名称空间中声明的名称与全局 JNDI 名称空间中目标资源的名称之间提供链接。<resource-ref name="com.ejbs.BankAccountServiceBean/dataSource" binding-name="jdbc/Default"/>需要 name 和 binding-name 属性。可包括 authentication-alias 或 custom-login-configuration 属性。<resource-env-ref>解析 resource-env-ref 声明的目标,该目标是通过 @Resource 注释或通过 ejb-jar.xml 中的 resource-env-ref 进行声明,在组件作用域的 java:comp/env 名称空间中声明的名称与全局 JNDI 名称空间中目标资源环境的名称之间提供链接。<resource-env-ref name="com.ejbs.BankAccountServiceBean/dataFactory" binding-name="jdbc/Default"/>需要 name 和 binding-name 属性。名称该属性标识命名位置,该位置通常位于特定于组件的 java:comp/env 名称空间中,用于在 ejb-ref、resource-ref、resource-env-ref、message-destination 或 message-destination-ref 等中定义引用/目标链接的“源”端。<ejb-ref name="com.ejbs.BankAccountServiceBean/goodBye" binding-name="ejb/session/S02"/> binding-name该属性标识命名位置,该位置位于 ejblocal: 或全局作用域的 JNDI 名称空间中,用于在 ejb-ref、resource-ref、resource-env-ref、message-destination 或 message-destination-ref 等中定义引用/目标链接的“目标”端。<ejb-ref name="com.ejbs.BankAccountServiceBean/goodBye" binding-name="ejb/session/S02"/> activation-spec-binding-name该属性标识与 JCA 1.5 适配器相关联的激活规范的 JNDI 位置,此适配器用于将消息传递至消息驱动的 bean。<jca-adapter activation-spec-binding-name="jms/InternalProviderSpec" destination-binding-name="jms/ServiceQueue"/>此名称必须与定义到 WebSphere Application Server 的 JCA 1.5 激活规范的名称相匹配。activation-spec-auth-alias该可选属性标识某一名称,该名称是用于认证到 JCA 资源适配器的连接的 J2C 认证别名名称。J2C 认证别名指定了用于认证创建到 JCA 资源适配器的新连接的用户标识和密码。<jca-adapter activation-spec-binding-name="jms/InternalProviderSpec" activation-spec-auth-alias="jms/Service47Alias" destination-binding-name="jms/ServiceQueue"/>此名称必须与定义到 WebSphere Application Server 的 J2C 认证别名的名称相匹配。destination-binding-name该属性标识 JNDI 名称,消息驱动的 bean 使用此名称在 JNDI 名称空间中查询它的 JMS 目标。<jca-adapter activation-spec-binding-name="jms/InternalProviderSpec" destination-binding-name="jms/ServiceQueue"/>此名称必须与定义到 WebSphere Application Server 的 JMS 队列或主题的名称相匹配。authentication-alias<resource-ref> 绑定元素的可选子元素。如果资源引用适用于连接工厂,那么可以指定可选的 JAAS 登录配置;在这种情况下,指的是简单认证别名。<resource-ref name="com.ejbs.BankAccountServiceBean/dataSource" binding-name="jdbc/Default"> <authentication-alias name="defaultAuth"/><resource-ref>此名称必须与定义到 WebSphere Application Server 的 JAAS 认证别名的名称相匹配。custom-login-configuration<resource-ref> 绑定元素的可选子元素。如果资源引用适用于连接工厂,那么可以指定可选的 JAAS 登录配置;在这种情况下,指的是一组属性(“名称/值”对)。<resource-ref name="com.ejbs.BankAccountServiceBean/dataSource" binding-name="jdbc/Default"> <custom-login-configuration-name="customLogin"> <property name="loginParm1" value="ABC123"/> <property name="loginParm2" value="DEF456"/> < /custom-login-configuration> </resource-ref>此名称必须与定义到 WebSphere Application Server 的 JAAS 登录配置的名称相匹配。

绑定文件示例 2

如下所示为示例 1 中介绍的基本 ibm-ejb-jar-bnd.xml 文件的扩展。
<?xml version="1.0" encoding="UTF-8"?><ejb-jar-bndxmlns="http://websphere.ibm.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd" version "1.0"><session name="S01" component-id="Department549/AccountProcessors"/><session name="S02" simple-binding-name="ejb/session/S02"/><session name="S03"><interface class="com.ejbs.BankAccountService" binding-name="ejblocal:session/BAS"/><ejb-ref name="com.ejbs.BankAccountServiceBean/goodBye" binding-name="ejb/session/S02"/><resource-ref name="com.ejbs.BankAccountServiceBean/dataSource" binding-name="jdbc/Default"/></session><message-driven-name="MO1">  <jca-adapter activation-spec-binding-name="jms/InternalProviderSpec" destination-binding-name="jms/ServiceQueue"/>  </message-driven><session name="S04" simple-binding-name="ejb/session/S04"><resource-ref name="ejbs.S04Bean/dataSource" binding-name="jdbc/Default"><authentication-alias name="defaultlogin"/></resource-ref></session><session name="S05"><interface class="com.ejbs.InventoryService" binding-name="ejb/session/S05Inventory"/><resource-ref name="ejbs.S05Bean/dataSource" binding-name="jdbc/Default"><custom-login-configuration name="customLogin"><property name="loginParm1" value="ABC123"/><property name="loginParm2" value="DEF456"/>      </custom-login-configuration></resource-ref></session></ejb-jar-bnd>
此绑定生成以下各项:
  1. 上一示例中名为 S01、S02 和 S03 的会话 bean 的业务接口和 home 接口绑定在本示例中保持不变。
  2. ejb-name 为“S03”的会话 bean 现在包含两个引用目标解析绑定:
    • ejb-ref 绑定将在 java:comp/env/com.ejbs.BankAccountServiceBean/goodBye 处定义的 EJB 引用解析为应用程序服务器根 JNDI 上下文中的 JNDI 位置 ejb/session/S02。EJB 引用也可能已由类 com.ejbs.BankAccountServiceBean 中对名为“goodBye”的实例变量执行的 @EJB 注入进行定义。
      注: ejb/session/S02 是会话 bean“S02”的 JNDI 位置(也已经在此绑定文件中定义),这意味着此引用指向名为“S02”的会话 bean。
    • resource-ref 绑定将在 java:comp/env/com.ejbs.BankAccountServiceBean/dataSource 处定义的资源引用解析为 JNDI 位置 jdbc/Default。该资源引用也可能已由类 com.ejbs.BankAccountServiceBean 中对名为“dataSource”的实例变量执行的 @Resource 注入进行定义。
  3. 绑定是对 ejb-name 为“M01”的消息驱动的 bean 定义的。MDB 使用 JCA 1.5 适配器(它的 JCA 1.5 激活规范已定义到 WebSphere Application Server,名为 jms/InternalProviderSpec)接收来自定义到 WebSphere Application Server 的 JMS 目标的消息,该 JMS 目标的 JNDI 名为 jms/ServiceQueue。
  4. ejb-name 为“S04”的会话 bean 可假定具有单个业务接口,该接口绑定至 ejb/session/S04(如果为远程接口)或 ejblocal:ejb/session/S04(如果为本地接口)。它具有一个名为 java:comp/env/ejbs/S04Bean/dataSource 的 resource-ref。它可能同时为类 ejbs.S04Bean,其 @Resource 注入到名为“dataSource”的变量中。此 resource-ref 解析为 JNDI 位置 jdbc/Default。resource-ref 引用 J2C 连接并使用名为“defaultlogin”的简单认证别名(已定义到 WebSphere Application Server)连接至此资源。
  5. 业务接口绑定是对类名为 com.ejbs.InventoryService(由 ejb-name 为“S05”的会话 bean 实现)的接口定义的;该接口可假定为远程接口(由于它不是以“ejblocal:”前缀作为开头),因此将绑定至全局作用域名称空间的服务器根 JNDI 上下文中的 ejb/session/S05Inventory。将对由此 bean 实现的任何其他业务接口指定缺省绑定。此 bean 具有一个名为 java:comp/env/ejbs.S05Bean/dataSource(或类 ejbs.S05Bean 中对名为“dataSource”的变量执行的 @Resource 注入)的 resource-ref,解析为 JNDI 位置 jdbc/Default。resource-ref 引用 J2C 连接并且将使用包含两个“名称/值”对的定制登录配置连接至此资源。

绑定文件示例 3

本示例说明如何定义和解析 EJB 引用绑定,以便在同一个 WebSphere Application Server 单元中跨应用程序服务器实例执行 JNDI 查询。它使用两个 EJB bean:一个被叫 bean 和一个主叫 bean。被叫 bean 使用 simple-binding-name 属性来定义显式绑定属性,而主叫 bean 执行 @EJB 注入并使用它的关联绑定文件中的 ejb-ref 元素来解析引用,以便它指向位于不同应用程序服务器进程中的被叫 bean。

ibm-ejb-jar-bnd.xml(被叫 bean)
<?xml version="1.0" encoding="UTF-8"?><ejb-jar-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ej    b-jar-bnd_1_0.xsd" version="1.0">      <session name="FacadeBean" simple-binding-name="ejb/session/FacadeBean"/></ejb-jar-bnd>
此绑定文件内容假定 ejb-name 为“FacadeBean”的会话 bean 将实现单个业务接口(并因此可使用 simple-binding-name 属性来替代 <interface> 子元素)。在这种情况下,FacadeBean 将实现单个远程业务接口,该接口被绑定至应用程序服务器的服务器根 JNDI 上下文(FacadeBean 所在的位置)中的 ejb/session/FacadeBean。
代码段(主叫 bean)
@EJB(name="ejb/FacadeRemoteRef")FacadeRemote remoteRef;try {output = remoteRef.orderStatus(input);   } catch (Exception e) {// Handle exception, etc.}
此代码段对名为“remoteRef”、类型为 FacadeRemote 的实例变量执行 EJB 资源注入。此注入覆盖“name”参数,将生成的 ejb-ref 引用名称设置为 ejb/FacadeRemoteRef。此代码将对所注入的引用调用业务方法。
ibm-ejb-jar-bnd.xml(主叫 bean)
<?xml version="1.0" encoding="UTF-8"?><ejb-jar-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-ejb-jar-bnd_1_0.xsd"   version="1.0">  <session name="CallingBean">    <ejb-ref name="ejb/FacadeRemoteRef" binding-name="cell/nodes/S35NLA1/servers/S35serverA1/ejb/session/FacadeBean"/>  </session></ejb-bnd-jar>
最后,此绑定文件将 ejb-ref 名为 ejb/FacadeRemoteRef 的 EJB 引用解析为指向 cell/nodes/S35NLA1/servers/S35serverA1/ejb/session/FacadeBean 的全局作用域 JNDI 名称。此全局作用域的 JNDI 名称表示一个绑定至名为“S35serverA1”的服务器(位于主叫 bean 的 WebSphere Application Server 单元中名为“S35NLA1”的节点上)的服务器根上下文处的 ejb/session/FacadeBean 的接口。为了指向其他 WebSphere Application Server 单元中的位置,可使用 CORBAName 样式的名称取代标准的 JNDI 名称。

可在更新应用程序文件的方法主题中找到有关如何修改 ibm-ejb-jar-bnd.xml 文件的指示信息。

注入和引用之间的关系

在注入伪指令与引用声明之间存在一对一联系:每个注入均隐式地定义某一类型的引用,相反,每个引用均可以根据情况定义一个注入。可将注入注释视为一种通过注释定义引用而不是在 XML 部署描述符中定义引用的机制。

缺省情况下,注入使用某一名称来定义引用,该名称由执行注入的组件的包限定类名、正斜杠(/)以及要在其中注入的变量或属性的名称构成。例如,在类 com.ejbs.AccountService 中对名为“depositService”的变量或属性执行的注入将产生名为 java:comp/env/com.ejbs.AccountService/depositService 的引用。但是,对注入伪指令指定可选的“name”参数会覆盖此缺省名称,并导致根据“name”参数的值命名此引用。

如果知道此规则,那么就很容易弄清楚如何做到:使用绑定文件不但解析在 XML 部署描述符中声明的引用的目标,而且解析由注释注入伪指令隐式声明的引用的目标。只需使用注入注释上“name”参数的值,或使用类名和变量/属性名称的缺省引用名称(如果未指定任何“name”参数),就如同它是在 XML 部署描述符中声明的名称。

EJB 引用和 EJB 注入的缺省解析

自动链接功能。

自动链接是 WebSphere Application Server 的一个增值功能,使不必要在某些使用方案中显式地解析 EJB 引用目标。在 Feature Pack for EJB 3.0 中,自动链接是在每个 WebSphere Application Server 进程的边界内实现的。自动链接算法的工作原理如下。

当 WebSphere Application Server EJB 容器在给定 EJB 模块中遇到 EJB 引用时,它首先会检查以确定您是否通过在模块的绑定文件中添加某一条目来显式地解析了该引用的目标。如果在绑定文件中找不到目标的任何显式解析,那么该容器将在引用模块中搜索某一实现您在引用中定义的接口类型的企业 bean。如果它在模块中刚好找到一个实现该接口的企业 bean,那么它将使用该企业 bean 作为 EJB 引用的目标。如果该容器在此模块中找不到该类型的企业 bean,那么它会将搜索范围扩展至此模块所属的应用程序,然后在该应用程序中搜索与引用模块一样被指定给同一应用程序服务器的其他模块。再者,如果此容器在应用程序的其他模块(与引用模块一样被指定给同一服务器)中刚好找到一个实现目标接口的企业 bean,那么它将使用该企业 bean 作为引用目标。

自动链接的作用域限于 EJB 引用所在的应用程序及指定了引用模块的应用程序服务器。对其他应用程序中的企业 bean、指定给其他应用程序服务器的模块中的企业 bean 或者位于已指定给 WebSphere Application Server 集群的模块中的企业 bean 的引用都必须使用 EJB 模块的 ibm-ejb-jar-bnd.xml 文件或 Web 模块的 ibm-web-bnd.xmi 文件中的引用目标绑定来显式地解析。

必须注意,虽然 EJB 容器、Web 容器和应用程序客户机容器支持自动链接,但仅 EJB 引用支持自动链接,其他类型的引用均不支持。此外,由于在指定了引用模块的服务器(对于 Java EE 客户机容器,则为客户机容器已配置为它的 JNDI 引导服务器的服务器)的 EJB 3.0 功能部件包中自动链接功能的作用域是受限制的,因此自动连接功能当前主要用于开发环境和其他单服务器使用方案。即使存在这些局限性,但它对帮助加速开发过程仍很有用。

集群环境和跨服务器环境中的命名注意事项

前面各个部分中的全局 JNDI 命名约定在非集群环境中以及在查询目标位于查询源所在的集群中时适用。从集群外部对给定集群中的绑定执行查询时,必须根据以下约定对查询字符串进行限定以指示目标所在的集群的名称:
cell/clusters/<cluster-name>/<name-binding-location>    
例如,假定 EJB 接口绑定位置在应用程序服务器根上下文中:
ejb/Department549/AccountProcessors/CheckingAccountReconciler  
如果将实现此接口的 EJB 指定给隶属于名为 Cluster47 的集群的应用程序服务器,那么该集群外部的查询字符串如下所示:
cell/clusters/Cluster47/ejb/Department549/AccountProcessors/CheckingAccountReconciler  
跨应用程序服务器进程执行查询时,必须根据以下约定对查询字符串进行限定以指示目标所在的节点和服务器的名称:
cell/nodes/<node-name>/servers/<server-name>/<name binding location> 
再次假定 EJB 接口绑定位置在应用程序服务器根上下文中:
ejb/Department549/AccountProcessors/CheckingAccountReconciler 
如果将实现此接口的企业 bean 指定给位于节点 S47NLA1 上的应用程序服务器 Server47A1,那么跨服务器查询字符串如下所示:
cell/nodes/S47NLA1/servers/Server47A1/ejb/Department549/AccountProcessors/CheckingAccountReconciler 

旧的(XMI)绑定

现有模块和应用程序可继续使用产品中提供的旧绑定支持,因此,可使用现有工具和向导为应用程序和模块指定绑定和扩展信息。旧支持仅适用于使用 J2EE 1.4 样式的 XML 部署描述符的 EAR 文件和模块。

使用 V3.0 XML 部署描述符模式或没有 XML 部署描述符文件的 EJB 模块必须使用缺省绑定和自动链接或者用户指定的 XML 绑定文件。

必须始终用 2.1 XML 部署描述符模式版本将 CMP 实体 bean 封装在模块中,以便可以使用现有工具来提供映射、绑定和扩展支持。

用户指定的 XML 绑定

每个接口的缺省绑定和每个引用的自动链接引用解析均可以通过指定 EJB 模块的绑定或通过创建 META-INF/ibm-ejb-jar-bnd.xml 文件来覆盖。

描述该格式的模式文件位于 <WAS_HOME>/properties/schemas 目录中。这种格式的绑定规范只能用于不包含 XML 部署描述符或者包含 EJB 3.0 部署描述符的模块。
注: 不必要指定所有绑定。任何未定义的绑定名称或引用均使用缺省绑定和自动链接支持。
可以为以下各项指定绑定:
  • 使用 <session> 元素的会话 bean
  • 使用 <message-driven> 元素的消息驱动的 bean
<session> 元素仅支持以下属性和子元素:
  • id 属性
  • name 属性
  • simple-binding-name 属性
  • component-id 属性
  • ejb-ref 元素
  • resource-ref 元素及其属性
  • resource-env-ref 元素及其属性
  • message-destination-ref 元素及其属性
<message-driven> 元素仅支持以下属性和子元素:
  • id 属性
  • name 属性
  • jca-adapter 属性
  • ejb-ref 元素及其属性
  • resource-ref 元素及其属性
  • resource-env-ref 元素及其属性
  • message-destination-ref 元素及其属性