将 JAX-RS 2.0 与 EJB 和 CDI 集成

Liberty 中的 JAX-RS 2.0 与 Enterprise JavaBeans (EJB) 及上下文和依赖关系注入 (CDI) 集成。

为使 JAX-RS 2.0 使用企业 bean,您需要使用 @Path 注释 bean 的类并将其转换为根资源类。

通过与 EJB 集成,您可注释 EJB bean 以将它们展示为 REST 端点。还可使用 EJB 的 JTA 和安全功能。Liberty 中的 JAX-RS 2.0 支持使用无状态 bean 和单独会话 bean 作为根资源类、提供者和应用程序子类。通过与 CDI 集成,您可注释 CDI bean 或受管 bean 作为 REST 端点并对 Web Service 使用 CDI 注入。Liberty 中的 JAX-RS 2.0 支持 CDI 样式的 bean 作为根资源类、提供者和应用程序子类。提供者和应用程序子类必须是单体或使用应用程序范围。CDI 规范简化了集成不同类型的 Java™ EE 组件的过程。它提供可将组件(例如 EJB 组件或受管 bean)注入其他组件(例如 JSP 或其他 EJB)的一种常用机制。

对于 EJB,可将注释与无状态会话 bean 和单体 POJO bean 配合使用。
  • 对于无状态会话 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 规范,只能对 JAX-RS 使用带有缺省构造函数的 EJB。
  • 如果在 Java 类中使用 EJB 或 CDI 注释,但未在 server.xml 文件中配置 EJB(例如,ejbLite-3.2)或 CDI(例如,cdi-1.0)的 Liberty 功能部件(这意味着 Liberty 运行时中没有 EJB 或 CDI 支持),那么 JAX-RS 2.0 引擎使用 Java 类作为 POJO 类。
  • 对于应用程序类,如果它未实现任何接口或者它具有 @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 无状态 无状态
  perRequest 单体 单体
  单体 无状态 无状态
  单体 单体 单体
提供者 单体 无状态 无状态
  单体 单体 单体

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 Session
  perRequest   perRequest
  单体 @ApplicationScoped 单体
  单体 @RequestScoped perRequest
  单体 @Dependent 单体
  单体 @SessionScoped 会话
  单体   单体
提供者 单体 @ApplicationScoped 单体
  单体 @RequestScoped 单体
  单体 @Dependent 单体
  单体 @SessionScoped 单体
  单体   单体

JAX-RS 2.0 范围和 CDI 范围生命周期冲突消息

如果 JAX-RS 2.0 与 CDI 两者的范围生命周期冲突,那么会显示以下警告消息。它们只是警告消息,不需要执行任何操作。

  • CWWKW1001W: JAXRS-2.0 资源 {0} 的范围 {1} 与 CDI 范围 {2} 不匹配。Liberty 从 {3} 获取资源实例。
    如果 JAXRS-2.0 资源范围与 CDI 范围不匹配并且 CDI 中存在该资源实例(导致 Liberty 从 CDI 获取该资源实例),那么会显示此消息。如果实例来自 JAX-RS,那么它未包含 CDI 注入。
  • CWWKW1002W: JAXRS-2.0 提供者 {0} 的 CDI 范围为 {1}。Liberty 从 {2} 获取该提供者实例。
    显示此消息的原因是该提供者实例仅为“单体”。如果该提供者的 CDI 范围是“依赖”或 ApplicationScoped,那么 Liberty 从 CDI 获取该提供者实例。如果实例来自 JAX-RS,那么它未包含 CDI 注入。

用于指示主题类型的图标 参考主题



时间戳记图标 最近一次更新时间: Tuesday, 6 December 2016
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=rwlp_jaxrs2.0_ejbcdi
文件名:rwlp_jaxrs2.0_ejbcdi.html