简体   繁体   English

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

[英]Declaring @Resource and @EJB at the class level in Java EE6

Is there any situation still ( given that Java EE6 has java:global/, app/, module/ naming standards) that necessitates declaring EJBs or Resources like the example below?是否还有任何情况(鉴于 Java EE6 具有 java:global/, app/, module/ 命名标准)需要声明 EJB 或资源,如下例所示?

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

}

Looking up PlaceBid in the helper class used by ActionBazaarBidControllerServletActionBazaarBidControllerServlet使用的助手 class 中查找 PlaceBid

PlaceBid placeBid = (PlaceBid)context.lookup("java:comp/env/ejb/PlaceBid");

The java:comp/env/ namespace is sometimes a little understood feature. java:comp/env/命名空间有时是一个鲜为人知的特性。 This namespace corresponds to what is called the Enterprise Naming Context (ENC).此命名空间对应于所谓的Enterprise Naming Context (ENC)。

It's like a private "hashmap" associated with each component, with the entire web module being treated as one component and individual EJB beans each being components as well.它就像一个与每个组件关联的私有“哈希图”,整个 web 模块被视为一个组件,并且每个 EJB bean 也都是组件。

You use this private namespace mostly for aliasing purposes .您将此私有名称空间主要用于别名目的 If you map something under "ejb/PlaceBid", then all (helper) code can use "ejb/PlaceBid" and at one global location (the servlet in this case, but it could also be XML) you can determine what is exactly mapped to it.如果您 map 位于“ejb/PlaceBid”下,那么所有(帮助程序)代码都可以使用“ejb/PlaceBid”并且在一个全局位置(在这种情况下是 servlet,但也可以是 XML),您可以确定准确映射的内容给它。 If all code went directly to java:global/... then there might be dozens of hardcoded dependencies to this name.如果所有代码都直接转到java:global/...那么这个名称可能有几十个硬编码依赖项。

So, you would use this if you need the extra redirection.所以,如果你需要额外的重定向,你会使用它。


Some other things to note:其他一些需要注意的事项:

1. With the EJB SessionContext you can reference this namespace directly, as-in: 1. 使用 EJB SessionContext,您可以直接引用此命名空间,如下所示:

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

Here "ejb/PlaceBid" is a relative name into the ENC.这里“ejb/PlaceBid”是 ENC 中的相对名称。

2. As mentioned, the ENC is private for each component. 2. 如前所述,ENC 对每个组件都是私有的。 Different EJBs can have a given relative name mapped differently.不同的 EJB 可以具有不同映射的给定相对名称。 context.lookup("java:comp/env/ejb/PlaceBid") can thus return something different depending on from which component you make the call. context.lookup("java:comp/env/ejb/PlaceBid")因此可以返回不同的东西,具体取决于您从哪个组件进行调用。

3. Historically, the ENC predated what we now call injection . 3. 从历史上看,ENC 早于我们现在所说的注入 In a way, when you specified a mapping in XML, you 'injected' something into the private "hashmap" associated with that component.在某种程度上,当您在 XML 中指定映射时,您将某些内容“注入”到与该组件关联的私有“哈希映射”中。 The modern version injects into fields, constructors or properties (setters), but the old version injected into 'keys'.现代版本注入字段、构造函数或属性(设置器),但旧版本注入“键”。

Even in EJB3.1, the historical 'injection' mechanism is still active under the hood.即使在 EJB3.1 中,历史上的“注入”机制在底层仍然是活跃的。 If you perform a seemingly normal injection using @EJB on a field, then this also automatically creates an entry in the JNDI ENC.如果您在字段上使用@EJB 执行看似正常的注入,那么这也会自动在 JNDI ENC 中创建一个条目。 Eg例如

package test;

@Stateless
public class MyBean {

   @EJB
   private MyService myService;

}

In this case, whatever is injected into myService is also stored in the ENC under name java:comp/env/test.MyBean/myService .在这种情况下,注入 myService 的任何内容也都存储在 ENC 中,名称为java:comp/env/test.MyBean/myService To complete the link with the @EJB annotation you used on the Servlet: you can optionally use the name attribute to specify the name under which the reference is stored in the ENC:要使用您在 Servlet 上使用的 @EJB 注释完成链接:您可以选择使用name属性来指定在 ENC 中存储引用的名称:

@Stateless
public class MyBean {

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

}

A little counter-intuitive, but in most cases the name attribute here is thus not something that points to a source where the object to be injected is taken from, but it's used as a target in the ENC to inject into.有点违反直觉,但在大多数情况下,此处的name属性并不指向要注入的 object 的来源,而是用作 ENC 中的目标注入。

Declaring a reference using a class-level annotation and declaring a reference using a java:module, java:app, or java:global name are distinct features.使用类级别注释声明引用和使用 java:module、java:app 或 java:global 声明引用是不同的名称。

You would use a class-level annotation to declare a reference if you don't need injection but you don't want to use XML.如果您不需要注入但又不想使用 XML,则可以使用类级别的注释来声明引用。

You would use a java:module, java:app, or java:global name (regardless of how the reference is defined) if you want multiple components in the module, app, or server to have access to the same reference.您将使用 java:module、java:app 或 java:global 名称(如果您想要访问多个组件引用的方式相同,或服务器中的引用)。 For example, so that you are only required to define a binding for the reference once rather than repeating the same binding information for each identical binding in the module (or in the app or for all apps in the server).例如,您只需为引用定义一次绑定,而不是为模块中的每个相同绑定(或应用程序或服务器中的所有应用程序)重复相同的绑定信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM