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

是否有任何情况(鉴于Java EE6具有java:global /,app /,模块/命名标准),需要声明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"); 

java:comp/env/ namespace有时候是一个有点了解的function。 此命名空间对应于所谓的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")因此可以返回不同的内容,具体取决于您调用哪个组件。

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

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

 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中的目标

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

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

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