簡體   English   中英

消除EJB注釋和注入

[英]Demistifying EJB annotations and injection

目前,我對Glassfish 3.1.2.2處理EJB的方式感到困惑。

我有一個OSGi項目,其中包含許多OSGi捆綁包(罐)。 另外,還有一些WAR,包括Tapestry Web應用程序。

在一個這樣的包中,我們將其稱為“ interfaces.jar”,我定義了一個接口:

public interface MyInterface() {
    public static final String JNDI_NAME = "java:global/MyInterface";
    void myMethod();
}

該接口的實現如下,它包含在捆綁包“ beans.jar”中:

@Stateless
@EJB(name = MyInterface.JNDI_NAME, beanInterface = MyInterface)
public class MyBean implements MyInterface() {
    void myMethod() {
        ...
    }
}

我通過JNDI查找從我的Tapestry WAR應用程序中調用它:

InitialContext.doLookup(MyInterface.JNDI_NAME);

現在,我正在閱讀EJB 3.1規范,它說我可以采用以下方案之一:

  1. 接口具有@Local批注; EJB正在實現此接口。
  2. 接口是沒有注釋的純Java接口。 具有@Local批注的EJB正在實現它。
  3. 接口是沒有注釋的純Java接口。 EJB正在實現它。
  4. 接口是沒有注釋的純Java接口。 具有@Local批注的EJB沒有實現它。
  5. EJB沒有任何特殊的注釋。

因此,通過消除:

  1. 我的界面上沒有@Local
  2. 我在EJB上沒有@Local
  3. 似乎有些正確
  4. 我在EJB上沒有@Local
  5. 我的EJB上有@EJB注釋

因此,似乎是情況3:

“因為它是EJB唯一實現的接口,所以容器假定它必須是本地業務接口。”

現在,有幾個問題:

  1. 由於沒有本地或遠程注釋,我的接口是本地還是遠程接口?
  2. 如果它是本地的,我應該可以使用@EJB注釋將其注入,但是失敗了嗎?
  3. 如果是遠程的,是否不符合上面幾行的說明?
  4. 如果我添加@Local@Remote並執行JNDI查找,則會得到一個命名異常,並且NPE告訴我該JNDI_NAME下沒有任何JNDI_NAME 那怎么可能?
  5. @EJB(name = ..., beanInterface = ...)對bean類的作用是什么?它如何與@Local@Remote批注交互?

1.)首先,讓我們看一下沒有“不必要” @EJB注釋的示例

@Stateless
public class MyBean implements MyInterface() {
    void myMethod() {
        ...
    }
}

現在您可以清楚地看到EJB僅實現了一個接口。 正如您在第3點中提到的那樣,“接口是沒有注釋的普通Java接口; EJB正在實現它。”因此MyInterface是MyBean EJB的本地業務接口。

2.)

您使用錯誤的JNDI名稱進行查找:

@Stateless
public class MyBean implements MyInterface() {
    ...

EJB的全局JNDI名稱:

java:global[/app-name][/module-name]/MyBean[!interface-name]

接口名稱為“ MyInterface”,但如果沒有其他可用於您的bean的業務接口(例如此處),則它是可選的,因此可以跳過它。

對於OSGI,您必須弄清楚bean的應用程序名稱和模塊名稱是什么。 在一個簡單的EJB應用程序中,application-name是.ear文件的名稱,而module-name是.war / .jar文件的名稱。 如果您的模塊未包裝在耳邊,則可以跳過application-name。

因此,例如:

new InitialContext().lookup("java:global/myModuleName/MyBean");

5.)

@Stateless
@EJB(name = "MyInterface", beanInterface = MyInterface.class)
public class MyBean implements MyInterface() {
    void myMethod() {
        ...
    }
}

在這里,@ EJB注釋創建一個EJB,並將對它的引用放入環境命名上下文(ENC)中。 因此,它對MyBean EJB無效,只需使用新條目擴展其ENC。

因此,從當前bean的業務方法中,您可以查找該新條目:

    void myMethod() {
        new InitialContext().lookup("java:comp/env/MyInterface")
    }

您可以通過“ java:comp / env /” JNDI名稱找到bean的ENC。

如您所見, name參數定義了ENC中條目的名稱。

beanInterface定義了創建的Bean的業務接口。 如果Bean具有更多的業務接口,那么您也必須定義beanName,以便容器可以確定要創建的夾心Bean。

您可以在此處閱讀有關此主題的信息: http : //thegreyblog.blogspot.hu/2010/09/introduction-to-ejb-30-injection-and.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM