将应用程序安装在应用程序服务器上后,必须将该应用程序中定义的所有 Enterprise JavaBeans(EJB)引用和资源引用都绑定至应用程序服务器上定义的实际工件(企业 bean 或资源),然后才能启动该应用程序。
当定义绑定时,请在应用程序中为可引用对象和已引用工件指定 Java 命名和目录接口(JNDI)名称。对工件指定的 jndiName 值必须是限定的查询名。
不需要手动为 EJB 3.0 模块中企业 bean 上的各个接口或 EJB home 接口指定 JNDI 绑定名称。如果未显式地指定绑定,那么 EJB 容器将指定缺省绑定。
本地 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 模块封装在 Java EE 应用程序归档中,而 Java EE 组件又封装在 Java EE 模块中,因此可根据每个组件的“嵌套路径”中的应用程序名称、模块名和组件名称来唯一地标识 Java EE 应用程序归档中的每个组件。
应用程序名称
模块名
模块的名称定义为模块文件的统一资源标识(URI),该 URI 相对于 EAR 文件根目录。换句话说,模块名是相对于 EAR 文件根目录的模块文件名,其中包括任何嵌套了该模块文件的“子目录”。
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 3.0 支持的如下绑定:
在 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”子上下文,而不是将其直接放置在服务器根上下文中。这样做的原因类似于使用磁盘卷上的子目录,而不是将所有文件都放入根目录中。
总之,所有本地缺省绑定,格式不论长短,均被放入 ejblocal: 服务器/JVM 作用域名称空间中,而对于远程缺省绑定而言,如果为短格式,就被放入全局作用域的名称空间中,否则被放入
描述 | 绑定模式 |
---|---|
短格式本地接口和 home 接口 | ejblocal: |
短格式远程接口和 home 接口 | |
长格式本地接口和 home 接口 | ejblocal: |
长格式远程接口和 home 接口 | ejb/ |
多个企业 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)。
对缺省绑定进行显式指定的影响
如果要手动指定绑定位置,而不使用 WebSphere 产品缺省绑定,那么您可以使用 EJB 模块绑定文件将您自己的绑定位置指定给特定接口和 home 接口。也可以使用此文件仅覆盖模块中一个或多个企业 bean 上的缺省绑定的组件标识部分。如果覆盖组件标识,那么可以在允许绑定完全使用缺省值与完全指定每个接口的绑定名称之间提供一定的回旋余地。
元素或属性 | 使用方法 | 示例 | 注释 |
---|---|---|---|
为会话 bean 声明一组绑定指定。 | 需要 name 属性及下列其中的一项或多项:simple-binding-name 属性、local-home-binding-name 属性、remote-home-binding-name 属性或 |
||
name | 该属性标识 |
ejb-name 值是在 ejb-jar.xml 部署描述符文件的 |
|
component-id | 该属性覆盖企业 bean 的缺省组件标识值。此企业 bean 的缺省长格式绑定使用指定的组件标识取代 |
上述示例将生成一个 bean,它的 ejb-name 是 AccountServiceBean,它的长格式缺省本地接口被绑定至以下位置:
ejblocal:Department549/AccountProcessor#<package.qualified.interface>它的长格式缺省远程接口被绑定至以下位置: ejblocal:Department549/AccountProcessor#<package.qualified.interface> |
可单独使用,或与 由于 simple-binding-name 属性适用于给定企业 bean 上的所有已定义接口(任何接口均不使用缺省值),因此通常没必要将 component-id 与 simple-binding-name 一起使用。 |
simple-binding-name | 一种简单机制,用于指定 Enterprise JavaBeans 的接口绑定以:
|
此示例将生成一个 bean,它的 ejb-name 是 AccountServiceBean,它的本地业务接口或 home 接口(如果有的话)被绑定至局部 JVM 作用域的 EJB 名称空间中的以下位置:
ejblocal:ejb/AccountService它的远程业务接口或 home 接口(如果有的话)被绑定至全局作用域的 JNDI 名称空间的应用程序服务器根上下文中的以下位置: ejb/AccountService。必须注意此处使用了该属性(包括此特定示例中的该属性)的准确值(“ejb”子上下文名称),即使接口是被绑定至 ejblocal: 名称空间的本地接口亦如此。如果指定了用户定义的绑定,那么将使用该属性指定的准确名称。 |
不要将其与 local-home-binding-name 属性、remote-home-binding-name 属性或 如果在实现多个业务接口的企业 bean 上使用此属性,或者将业务接口和本地/远程组件接口与 home 接口一起使用,那么可通过如下方法来确保生成的绑定没有歧义:在属性值后面添加破折号或编号符号(# 符号),紧随其后是企业 bean 上每个接口和/或 home 接口的包限定类名。然而,可使用 要点:在 bean 上定义 simple-binding-name 以实现多个业务接口与使用 |
local-home-binding-name | 该属性用以指定企业 bean 的本地 home 接口的绑定位置。 | 不要将其与 simple-binding-name 属性一起使用。由于本地 home 接口必须始终绑定至 JVM 作用域的名称空间,因此该值必须始终以 ejblocal: 前缀开头。 | |
remote-home-binding-name | 该属性用以指定企业 bean 的远程 home 接口的绑定位置。 | 不要将其与 simple-binding-name 属性一起使用。由于远程 home 接口无法绑定至 ejblocal: 名称空间,因此该值不能以 ejblocal: 前缀开头。 | |
不要将其与 simple-binding-name 属性一起使用。由于本地接口必须始终绑定至 JVM 作用域的名称空间,因此将此元素应用于本地接口时,binding-name 值必须始终以 ejblocal: 前缀开头。 | |||
binding-name | 该属性用以指定使用 |
必须与 |
绑定文件示例 1
该绑定文件生成以下各项:
ejblocal:Department549/AccountProcessors#<package.qualified.interface.name>而远程接口被绑定至以下位置:
ejb/Department549/AccountProcessors#<package.qualified.interface.name>
ejblocal:ejb/session/S02(如果是它是本地接口),或者被绑定至以下位置:
ejb/session/S02(如果它是远程接口)。
如果 bean S02 具有多个业务接口或多个业务接口和 home 接口,那么 simple-binding-name 就有歧义。在该情况下,此容器通过在该 bean 的各个接口的简单绑定名称 ejb/session/S02 后面添加 #<package.qualified.interface.name> 来消除绑定指定的歧义。
下一部分将扩展此示例,引入一些元素,用于解析在 XML 部署描述符中或通过注释来声明的各种引用和注入条目的目标。
前一部分说明了如何对业务接口和 home 接口指定用户定义的绑定名称。此部分说明如何解析引用、注入伪指令和消息驱动的 bean 目标的链接目标。
元素或属性 | 使用方法 | 示例 | 注释 |
---|---|---|---|
解析 ejb-ref 声明的目标,该目标是通过 @EJB 注释或通过 ejb-jar.xml 部署描述符中的 ejb-ref 进行声明,在组件作用域的 java:comp/env 名称空间中声明的名称与 JVM 作用域的 ejblocal: 或全局作用域的 JNDI 名称空间中的目标企业 bean 的名称之间提供链接。 | 需要 name 和 binding-name 属性。 | ||
为消息驱动的 bean 声明一组绑定指定。 | 需要 name 属性和 |
||
定义 JCA 1.5 适配器激活规范和消息目标 JNDI 位置,用于将消息传递至消息驱动的 bean。 | 需要 activation-spec-binding-name 和 destination-binding-name 属性。可根据情况包括 activation-spec-auth-alias 属性。 | ||
将消息目标的名称(它是在 Java EE 模块部署描述符中定义的逻辑名称)与特定全局 JNDI 名称(它是 JNDI 名称空间中的实际名称)相关联。Java EE 模块部署描述符中的 |
需要 name 和 binding-name 属性。 | ||
解析 message-destination-ref 声明的目标,该目标是通过 @Resource 注释或通过 ejb-jar.xml 中的 message-destination-ref 进行声明,在组件作用域的 java:comp/env 名称空间中声明的名称与全局 JNDI 名称空间中目标资源环境的名称之间提供链接。 | 需要 name 和 binding-name 属性。 | ||
解析 resource-ref 声明的目标,该目标是通过 @Resource 注释或通过 ejb-jar.xml 中的 resource-ref 进行声明,在组件作用域的 java:comp/env 名称空间中声明的名称与全局 JNDI 名称空间中目标资源的名称之间提供链接。 | 需要 name 和 binding-name 属性。可包括 authentication-alias 或 custom-login-configuration 属性。 | ||
解析 resource-env-ref 声明的目标,该目标是通过 @Resource 注释或通过 ejb-jar.xml 中的 resource-env-ref 进行声明,在组件作用域的 java:comp/env 名称空间中声明的名称与全局 JNDI 名称空间中目标资源环境的名称之间提供链接。 | 需要 name 和 binding-name 属性。 | ||
名称 | 该属性标识命名位置,该位置通常位于特定于组件的 java:comp/env 名称空间中,用于在 ejb-ref、resource-ref、resource-env-ref、message-destination 或 message-destination-ref 等中定义引用/目标链接的“源”端。 | ||
binding-name | 该属性标识命名位置,该位置位于 ejblocal: 或全局作用域的 JNDI 名称空间中,用于在 ejb-ref、resource-ref、resource-env-ref、message-destination 或 message-destination-ref 等中定义引用/目标链接的“目标”端。 | ||
activation-spec-binding-name | 该属性标识与 JCA 1.5 适配器相关联的激活规范的 JNDI 位置,此适配器用于将消息传递至消息驱动的 bean。 | 此名称必须与定义到 WebSphere Application Server 的 JCA 1.5 激活规范的名称相匹配。 | |
activation-spec-auth-alias | 该可选属性标识某一名称,该名称是用于认证到 JCA 资源适配器的连接的 J2C 认证别名名称。J2C 认证别名指定了用于认证创建到 JCA 资源适配器的新连接的用户标识和密码。 | 此名称必须与定义到 WebSphere Application Server 的 J2C 认证别名的名称相匹配。 | |
destination-binding-name | 该属性标识 JNDI 名称,消息驱动的 bean 使用此名称在 JNDI 名称空间中查询它的 JMS 目标。 | 此名称必须与定义到 WebSphere Application Server 的 JMS 队列或主题的名称相匹配。 | |
authentication-alias | 此名称必须与定义到 WebSphere Application Server 的 JAAS 认证别名的名称相匹配。 | ||
custom-login-configuration | 此名称必须与定义到 WebSphere Application Server 的 JAAS 登录配置的名称相匹配。 |
绑定文件示例 2
此绑定生成以下各项:
绑定文件示例 3
本示例说明如何定义和解析 EJB 引用绑定,以便在同一个 WebSphere Application Server 单元中跨应用程序服务器实例执行 JNDI 查询。它使用两个 EJB bean:一个被叫 bean 和一个主叫 bean。被叫 bean 使用 simple-binding-name 属性来定义显式绑定属性,而主叫 bean 执行 @EJB 注入并使用它的关联绑定文件中的 ejb-ref 元素来解析引用,以便它指向位于不同应用程序服务器进程中的被叫 bean。
此绑定文件内容假定 ejb-name 为“FacadeBean”的会话 bean 将实现单个业务接口(并因此可使用 simple-binding-name 属性来替代
@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。此代码将对所注入的引用调用业务方法。
最后,此绑定文件将 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 部署描述符中声明的名称。
自动链接功能。
自动链接是 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 功能部件包中自动链接功能的作用域是受限制的,因此自动连接功能当前主要用于开发环境和其他单服务器使用方案。即使存在这些局限性,但它对帮助加速开发过程仍很有用。
cell/clusters/例如,假定 EJB 接口绑定位置在应用程序服务器根上下文中:/
ejb/Department549/AccountProcessors/CheckingAccountReconciler如果将实现此接口的 EJB 指定给隶属于名为 Cluster47 的集群的应用程序服务器,那么该集群外部的查询字符串如下所示:
cell/clusters/Cluster47/ejb/Department549/AccountProcessors/CheckingAccountReconciler跨应用程序服务器进程执行查询时,必须根据以下约定对查询字符串进行限定以指示目标所在的节点和服务器的名称:
cell/nodes/再次假定 EJB 接口绑定位置在应用程序服务器根上下文中:/servers/ /
ejb/Department549/AccountProcessors/CheckingAccountReconciler如果将实现此接口的企业 bean 指定给位于节点 S47NLA1 上的应用程序服务器 Server47A1,那么跨服务器查询字符串如下所示:
cell/nodes/S47NLA1/servers/Server47A1/ejb/Department549/AccountProcessors/CheckingAccountReconciler
现有模块和应用程序可继续使用产品中提供的旧绑定支持,因此,可使用现有工具和向导为应用程序和模块指定绑定和扩展信息。旧支持仅适用于使用 J2EE 1.4 样式的 XML 部署描述符的 EAR 文件和模块。
使用 V3.0 XML 部署描述符模式或没有 XML 部署描述符文件的 EJB 模块必须使用缺省绑定和自动链接或者用户指定的 XML 绑定文件。
必须始终用 2.1 XML 部署描述符模式版本将 CMP 实体 bean 封装在模块中,以便可以使用现有工具来提供映射、绑定和扩展支持。
每个接口的缺省绑定和每个引用的自动链接引用解析均可以通过指定 EJB 模块的绑定或通过创建 META-INF/ibm-ejb-jar-bnd.xml 文件来覆盖。