[java] @ Inject,@ EJB,@ Local,@ Remote,@ LocalBean等......:困惑?


Answers

@Inject註釋用於java bean(POJO),而@EJB註釋用於企業java bean。 當容器將@EJB註釋提供的ejb注入另一個bean時,它還控制ejb的生命週期,為無狀態bean執行池化等等(當未註入將要注入的bean時,引用將為null)。 如果使用@Inject註釋CDI機制,只需查找並創建一個注入資源的實例,就像使用new運算符一樣(如果將要注入的接口的實現不存在,則引用將為null)。 您可以使用帶有@Inject批註的限定符來選擇注入接口的不同實現。

Question

我有以下配置:

  • 1個包含2個帶EJB組件的EJB-JAR的GF上的EAR。
  • 1另一個Glassfish服務器( =>其他JVM )上的WAR包含訪問EJB組件的Web組件。

我在EAR的每個EJB-JAR中都有2個EJB業務服務,它們都是這樣開發的:

@Remote
public interface ServiceAItf {
    ...
}

@Stateless
@Local
public class ServiceAImpl implements ServiceAItf {
    ...
}

在我的WAR中,我通過遠程接口上的顯式“InitialContext.lookup”訪問EJB組件。

在我的EAR中,我對注入的最佳實踐非常困惑,無論是在性能,架構等方面......

我有以下問題:

  • 如您所見,我已在服務實現上聲明了註釋“@Local” ,而沒有定義本地接口。 這是對的嗎? 至少我在部署時沒有錯誤。 但也許我應該使用“@LocalBean”註釋? 我想“@LocalBean”註釋只允許直接調用實現作為“本地” EJB,但你必須在代碼中使用這樣的實現:

    @Stateless @Local public class ServiceBImpl實現ServiceBItf {@EJB private ServiceAImpl serviceA; ...}

  • 將一個EJB注入另一個EJB的最佳方法是什麼? 它的工作原理如下:

    @Stateless @Local public class ServiceBImpl實現ServiceBItf {@EJB private ServiceAItf serviceA; ...}

但是從我注意到的,注入的“serviceA”是遠程代理,而它位於同一個EAR文件中的同一個JVM中。 所以我認為會對性能產生影響。 這就是為什麼我試圖注入這樣的服務:

@Stateless
@Local
public class ServiceBImpl implements ServiceBItf {
    @Inject
    private ServiceAItf serviceA;
    ...
}

但它在GF中不起作用,我有以下例外:

WELD-001408 Unsatisfied dependencies for type [...] ...

然後我嘗試創建一個本地接口,並通過註釋“@Inject”注入兩個服務時都有效

即使我創建這樣的本地接口,服務也不會通過註釋“@Inject”注入,而是為null:

@Local
public interface ServiceALocalItf {
    ...
}

我閱讀了很多文章,強烈建議在本地調用時使用“@Inject”而不是“@EJB” 。 這引出了以下問題:在這種情況下,建議(或簡單地使用) “@Local” EJB調用?

經過所有這些分析,我得出以下結論:

  • 對於每個服務,我創建一個“@Local”和一個“@Remote”界面。
  • 從WAR到EAR的EJB-JAR,對遠程接口進行JNDI查找。
  • 從EJB-JAR到EJB-JAR,通過“@EJB”注入本地接口。
  • 對於同一EJB-JAR中的兩個服務,通過“@Inject”向本地接口注入。

你怎麼看待這件事? 這是對的嗎?




Related