JavaEE 7:没有接口的EJB jndi-name

2 java ejb jndi glassfish java-ee

我使用GF4服务器,在其日志中我有:

EJB com.test.cms.svr.web.Service2的可移植JNDI名称:[java:global/com.test.cms.svr.web_1.0.0/com.test.cms.svr.web.Service2,java:global/ com.test.cms.svr.web_1.0.0/com.test.cms.svr.web.Service2!com.test.fw.svr.web.bundle.ComponentService]]]

我的问题:

  1. 为什么有两个jndi名称 - 带接口和没有接口?
  2. 为什么我只能使用带接口的jndi-name来获取bean,即使EJB只是本地的?

unw*_*ich 5

为什么有两个jndi名称 - 带接口和没有接口?

这是一个名为可移植JNDI名称的EJB 3.1功能.以下是此博客的一个很好的解释:

客户端应用程序需要使用全局JNDI名称来查找EJB.ejb的所有规范都没有提及这种全球jndi名称的可移植性.这允许每个供应商以特定于供应商的方式为EJB分配全局jndi名称.这意味着使用全局JNDI名称执行查找的客户端代码在appserver供应商实现中本质上是不可移植的.

EJB 3.1通过强制每个容器必须为EJB分配(至少一个)定义良好的全局JNDI名称来解决上述问题.EJB的(可移植)全局JNDI名称的一般语法具有以下形式:

java:global/[<application-name>]/<module-name>/<bean-name>!<fully-qualified-bean-interface-name>

除了上面的名称,如果EJB只公开一个客户端视图(即它只实现一个接口或没有接口视图),那么容器也被强制将bean映射到

java:global/[<application-name>]/<module-name>/<bean-name>

哪里

  1. <application-name>默认为没有包扩展名的包名称(.ear文件名).这可以在application.xml中重写.此外,仅当bean打包在.ear文件中时才适用.
  2. <module-name>默认为捆绑名称(.war或.jar)而不包含扩展名.同样,这可以在ejb-jar.xml中重写.
  3. <bean-name>默认为bean的非限定类名.然而,如果@Stateful还是@Stateless@Singleton使用name属性,则该值规定有将用作bean的名称.

GlassFish EJB FAQ中还有一些额外的GlassFish特定信息.

为什么我只能使用带接口的jndi-name来获取bean,即使EJB只是本地的?

我猜你的意思是从同一个JVM内的同一个Web应用程序中的另一个EJB或模块进行查找.否则,如果没有@Remote接口,这是不可能的.以下是GlassFish EJB FAQ中的两个语句:

我有一个带有Local接口的EJB组件.我可以从Application Client或独立的Java客户端访问它吗?

如果EJB组件在服务器中运行,则不.EJB Local视图是一个使用call-by-reference语义的优化调用路径.它仅适用于与目标EJB组件属于同一应用程序一部分的Web组件和EJB组件.
要从Application Client或独立Java客户端访问服务器中运行的EJB组件,您需要使用Remote 3.x Business接口,2.x Home接口或Web服务.

如果使用GlassFish v3,另一种方法是使用EJB 3.1 Embeddable API.这允许Java SE程序直接在同一JVM中执行EJB组件,而无需使用服务器进程.

我有一个带有Local接口的EJB组件.我可以从其他应用程序中的Web组件访问它吗?

否.EJB规范仅需要从同一JVM中的同一应用程序内访问EJB组件的本地EJB接口.一种选择是将ejb-jar打包在与.war相同的.ear中.如果使用GlassFish v3,第二个选项是将EJB组件直接打包在.war中.

GlassFish EJB FAQ还包含有关此主题的更多详细信息.

也可以看看: