JAX-RS 2.0 與 EJB 和 CDI 的整合

Liberty 中的 JAX-RS 2.0 會與 Enterprise JavaBeans (EJB) 和「環境定義和相依關係注入 (CDI)」整合。

若要使 JAX-RS 2.0 使用 Enterprise Bean,您需要使用 @Path,來標註 Bean 的類別,並將它轉換成根目錄資源類別。

與 EJB 整合之後,您就可以標註 EJB Bean,使它們顯現成 REST 端點。您也可以使用 EJB 的 JTA 和安全功能。Liberty 中的 JAX-RS 2.0 支援使用 Stateless Session Bean 和單態階段作業 Bean,作為根目錄資源類別、提供者和應用程式子類別。與 CDI 整合之後,您就可以將 CDI Bean 或受管理 Bean 標註為 REST 端點,並將 CDI 注入用於 Web 服務。Liberty 中的 JAX-RS 2.0 支援使用 CDI 樣式的 Bean,作為根目錄資源類別、提供者和應用程式子類別。提供者和應用程式子類別必須是單態,或使用應用程式範圍。藉由 CDI 規格,整合不同類型的 Java™ EE 元件更容易。它提供一種通用機制,用來將 EJB 元件或受管理 Bean 之類的元件,注入至 JSP 或其他 EJB 之類的其他元件中。

對於 EJB,註釋可以用於 Stateless Session Bean 和單態 POJO Bean。
  • 在 Stateless Session Bean 方面,是如下列範例所示來使用 @Stateless 註釋:
    @Stateless
    @Path("stateless-bean")
    public class StatelessResource {...}
  • 在單態 Bean 方面,是如下列範例所示來使用 @Singleton 註釋:
    @Singleton
    @Path("singleton-bean")
    public class SingletonResource {...}
對於 CDI,@ApplicationScoped@Inject 註釋可以用於應用程式範圍的 Bean。
提示: 如果停用 CDI 特性,JAX-RS 不會報告錯誤,但是會利用 POJO 取得實例。
@ApplicationScoped
@Path("/ApplicationScopedResource")
public class ApplicationScopedResource {

    private @Inject
    SimpleBean injected;

...

}

JAX-RS 2.0 與 EJB 和 CDI 的限制

請參閱下列項目,以瞭解 Liberty 中的 JAX-RS 2.0 限制:

  • 如果您使用 EJB 作為 JAX-RS 資源、提供者或應用程式,則無法在 EJB Bean 的建構子上使用 @Context 注入。因為根據 EJB 和 JAX-RS 規格,具有預設建構子的 EJB 只能用於 JAX-RS。
  • 如果您在 Java 類別中使用 EJB 或 CDI 註釋,但是未在 server.xml 檔中配置 Liberty EJB 特性(例如 ejbLite-3.2)或 CDI 特性(例如 cdi-1.0),這表示 Liberty 執行時期不提供 EJB 或 CDI 支援,則 JAX-RS 2.0 引擎會使用 Java 類別作為 POJO 類別。
  • 對於 Application 類別,如果它沒有實作任何介面,或者它具有 @Localbean 註釋,則會將它視為 EJB;如果它會實作本端或 POJO 介面,就不會將它視為 EJB。
    • 在提供者方面:
      • 如果類別只實作 POJO 提供者介面,而沒有 @Local 註釋,會視之為有效的 EJB 提供者。
      • 如果類別具有 @LocalBean 註釋,且會實作 POJO 提供者介面,則會將它視為有效的 EJB 提供者。
      • 如果類別具有本端介面與 @Local 註釋,則本端介面是提供者介面。如果這個類別實作提供者介面,則它是有效的 EJB 提供者。
      • 如果類別具有本端介面與 @Local 註釋,且本端介面不是提供者介面,則它不是有效的提供者。

        這是因為在此情況下,EJB 儲存器只會針對本端介面(而不針對 POJO 提供者介面)產生 EJB 片段。

      • 如果類別只有 @Local 註釋,並且是參照提供者介面,但不會實作這個提供者介面,根據下列 JAX-RS 2.0 規格,它不是有效的提供者:提供者是一個會實作本規格所推出之一或多個 JAX-RS 介面的類別,並且可能標註 @Provider 以便自動探索。
    • 在資源方面:
      • 如果 EJB 型資源不會實作任何介面,這個類別中所宣告的所有方法會以 JAX-RS 資源形式提供。
      • 如果 EJB 型資源會實作一個介面(本端或 POJO),這個介面中所宣告的所有方法會以 JAX-RS 資源形式提供。
      • 如果 EJB 型資源會實作多個介面,
        1. 如果所有介面都是沒有 @Local 註釋的 POJO 介面,則介面中所宣告的所有方法會以 JAX-RS 資源形式提供。
        2. 如果所有介面都是具有 @Local 註釋的本端介面,則介面中所宣告的所有方法會以 JAX-RS 資源形式提供。
        3. 如果有些介面是具有 @Local 註釋的本端介面,而其他介面不是本端介面,則只有本端介面中所宣告的方法會以 JAX-RS 資源形式提供。這是因為 EJB 儲存器只會針對這個實務中的本端介面,產生 EJB 片段。
        4. 如果 EJB 型資源具有 @LocalBean 註釋,則類別中所宣告的所有方法會以 JAX-RS 資源形式提供。
        5. 如果 EJB 型資源會實作介面,則必須在介面中宣告 JAX-RS 資源方法。如果介面是一個無法修改的提供者,您必須為資源類別建立新介面,以新增資源方法。否則,不會視之為 EJB 資源。
  • 如果資源類別具有 @Path 註釋,且會實作 JAX-RS 提供者介面,或者它使用 @Provider 註釋來宣告,則這個類別同時擔任資源和提供者。在此情況下,依預設,JAX-RS 2.0 引擎只會使用這個類別的一個實例,並且是資源和提供者所共用的,且實例的生命週期是單態。
  • 如果類別同時登錄在應用程式類別的 getClasses 和 getSingletons 方法中,依預設,JAX-RS 2.0 引擎會使用 getSingletons 方法的實例,而忽略 getClasses 方法中的登錄。
  • 如果 RESTful 資源也是一個 CDI 受管理 Bean,且其範圍是 javax.enterprise.context.Dependent,基於 CDI 限制,無法呼叫 PreDestroy 方法。

JAX-RS 2.0 Bean 和 EJB Bean 的生命週期

JAX-RS Bean 和 EJB Bean 的生命週期不同。如果 JAX-RS 和 EJB 的 Bean 生命週期衝突,則會由 Liberty 中的 EJB 儲存器管理生命週期。因此當 JAX-RS 生命週期失效時,會套用 EJB 實例。如需相關資訊,請參閱下表:
表 1. JAX-RS 2.0 Bean 和 EJB Bean 的生命週期
應用程式 JAX-RS 2.0 EJB 結果
資源 perRequest Stateless Stateless
  perRequest 單態 單態
  單態 Stateless Stateless
  單態 單態 單態
提供者 單態 Stateless Stateless
  單態 單態 單態

JAX-RS 2.0 範圍和 CDI 範圍的生命週期

Bean 具有用來決定其實例生命週期的範圍。JAX-RS 和 CDI 的範圍略有不同。如果 JAX-RS 和 CDI 的範圍生命週期衝突,請見下表以瞭解其結果:
表 2. JAX-RS 2.0 範圍和 CDI 範圍的生命週期
應用程式 JAX-RS 2.0 範圍 CDI 範圍註釋 結果
資源 perRequest @ApplicationScoped 單態
  perRequest @RequestScoped perRequest
  perRequest @Dependent perRequest
  perRequest @SessionScoped 階段作業
  perRequest   perRequest
  單態 @ApplicationScoped 單態
  單態 @RequestScoped perRequest
  單態 @Dependent 單態
  單態 @SessionScoped 階段作業
  單態   單態
提供者 單態 @ApplicationScoped 單態
  單態 @RequestScoped 單態
  單態 @Dependent 單態
  單態 @SessionScoped 單態
  單態   單態

JAX-RS 2.0 範圍和 CDI 範圍的生命週期衝突訊息

當 JAX-RS 2.0 和 CDI 的範圍生命週期衝突時,會顯示下列警告訊息。這些是警告訊息,不需要採取動作。

  • CWWKW1001W: JAX-RS 2.0 資源 {0} 的範圍 {1} 不符合 CDI 範圍 {2}。Liberty 從 {3} 取得資源實例。
    如果 JAX-RS 2.0 資源範圍不符合 CDI 範圍,且資源實例存在於 CDI 中,使得 Liberty 從 CDI 取得資源實例時,就會顯示此訊息。如果 CDI 注入來自 JAXRS,則實例不包含 CDI 注入。
  • CWWKW1002W: JAX-RS 2.0 提供者 {0} 的 CDI 範圍是 {1}。Liberty 從 {2} 取得提供者實例。
    顯示此訊息的原因是提供者實例純為「單態」。如果提供者的 CDI 範圍是 Dependent 或 ApplicationScoped,則 Liberty 會從 CDI 取得提供者實例。如果 CDI 注入來自 JAXRS,則實例不包含 CDI 注入。

指示主題類型的圖示 參照主題

資訊中心條款 | 意見


「時間戳記」圖示 前次更新: 2016 年 4 月 15 日
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-libcore-mp&topic=rwlp_jaxrs2.0_ejbcdi
檔名:rwlp_jaxrs2.0_ejbcdi.html