在Java EE6中在类级别声明@Resource和@EJB

时间:2011-05-30 19:38:03

标签: java java-ee ejb-3.0 jndi

是否还有任何情况(假设Java EE6有java:global /,app /,module / naming) 标准)有必要像下面的例子那样声明EJB或资源吗?

@EJB (name = "ejb/PlaceBid", beanInterface = PlaceBid.class)
public class ActionBazaarBidControllerServlet extends HttpServlet {

}

ActionBazaarBidControllerServlet

使用的帮助程序类中查找PlaceBid
PlaceBid placeBid = (PlaceBid)context.lookup("java:comp/env/ejb/PlaceBid");

2 个答案:

答案 0 :(得分:18)

java:comp/env/命名空间有时是一个有点了解的功能。此命名空间对应于所谓的Enterprise Naming Context(ENC)。

它就像一个与每个组件关联的私有“hashmap”,整个Web模块被视为一个组件,各个EJB bean也是组件。

您主要使用此私有命名空间用于别名。如果您在“ejb / PlaceBid”下映射某些内容,那么所有(辅助)代码都可以使用“ejb / PlaceBid”并在一个全局位置(在本例中为servlet,但它也可以是XML),您可以确定完全映射的内容它。如果所有代码都直接转到java:global/...,则可能会有数十个硬编码的依赖关系到此名称。

所以,如果你需要额外的重定向,你可以使用它。


其他一些注意事项:

1。 使用EJB SessionContext,您可以直接引用此命名空间,如下所示:

PlaceBid placeBid = (PlaceBid)sessionContext.lookup("ejb/PlaceBid");

这里“ejb / PlaceBid”是ENC的相对名称。

2。 如上所述,ENC对每个组件都是私有的。不同的EJB可以以不同方式映射给定的相对名称。 context.lookup("java:comp/env/ejb/PlaceBid")因此可以返回不同的内容,具体取决于您调用哪个组件。

3。 从历史上看,ENC早于我们现在所说的 injection 。在某种程度上,当您在XML中指定映射时,您将'某些东西注入到与该组件关联的私有“hashmap”中。现代版本注入字段,构造函数或属性(setter),但旧版本注入'keys'。

即使在EJB3.1中,历史上的“注入”机制仍然处于活跃状态。如果在字段上使用@EJB执行看似正常的注入,那么这也会自动在JNDI ENC中创建一个条目。 E.g。

package test;

@Stateless
public class MyBean {

   @EJB
   private MyService myService;

}

在这种情况下,注入myService的任何内容也会以名称java:comp/env/test.MyBean/myService存储在ENC中。要完成与Servlet上使用的@EJB注释的链接:您可以选择使用name属性来指定引用存储在ENC中的名称:

@Stateless
public class MyBean {

   @EJB(name = "ejb/PlaceBid")
   private MyService myService;

}

有点反直觉,但在大多数情况下,这里的name属性不是指向要注入的对象的的东西,但是它被使用了作为注入的ENC中的目标

答案 1 :(得分:0)

使用类级别注释声明引用并使用java:module,java:app或java:global name声明引用是不同的功能。

如果您不需要注入但是不想使用XML,则可以使用类级别注释来声明引用。

如果您希望模块,应用程序或服务器中的多个组件可以访问相同的引用,则可以使用java:module,java:app或java:global name(无论引用是如何定义的)。例如,您只需要为引用定义一次绑定,而不是为模块中的每个相同绑定(或在应用程序中或服务器中的所有应用程序重复相同的绑定信息)。