JAX-RS:无状态、Singleton、RequestScoped混淆



我见过很多次配置JAXRS资源的方法。

我的意思是,有时我看到它们被注释为@Singleton@Stateless@ApplicationScoped@RequestScoped,甚至没有任何注释或同时使用它们。

  • javax.enterprise.context.RequestScoped
  • javax.enterprise.context.ApplicationScoped
  • javax.ejb.Stateless
  • javax.ejb.Singleton
  • javax.inject.Singleton

我应该使用哪个注释

javax.ejb与JAXRS资源有什么关系

另一方面,我也想知道如何准确地使用@Context注释。

我的意思是,我已经看到这个应用于参数,也应用于类字段

@Path("entity")
public class EntityResource {
@Context
private Request request;
@POST
public Response create(Entity entity) {
this.request...
}
}

或者,

@Path("entity")
public class EntityResource {
@POST
public Response create(Entity entity, @Context Request request) {
request...
}
}

我该如何处理?

在JAX-RS资源类中不需要使用任何EJB或CDI注释,除非您想在同一类中使用EJB或CDI功能。

如果您想将任何CDIBean注入到资源类中,那么资源类本身必须是CDIBean,因此您应该添加一个范围注释,最好是@javax.enterprise.context.RequestScoped

如果使用像@Stateless这样的EJB注释,那么注入也会起作用,因为EJB也是CDIBean(但不是相反)。然而,无状态bean有不同的生命周期,默认情况下它是事务性的。

另一方面,如果您需要事务,也可以将@javax.transaction.Transctional@RequestScoped@Path结合使用。

背景:

EJB对于大多数目的来说都有点过时了。它们首先出现在JAX-RS和CDI之前,但如今,CDI被视为Java EE/Jarta EE中统一的依赖注入机制,并且旧的规范正在更新中,以与CDI更紧密地集成。

关于您的第一个问题(托管bean范围),我想说不应该使用范围注释,因为javaee容器将根据Jax-rs注释自动管理您的bean的正确范围。

然而,ibm的人似乎对这个问题有不同的想法,并陈述了以下

最佳实践

向任何JAX-RS根资源和提供程序添加特定的生命周期作用域存在于应用程序中的类,位于启用了JCDI的归档中。对于带有@javax.ws.RS.Path注释的JAX-RS资源类,您可以使用@javax.enterprise.context.RequestScoped。Forjavax.ws.rs.core.Application子类和@javax.ws-rs.ext.Provider带注释的类,必须使用@javax.enterprise.context.ApplicationScoped.

关于@Context注释,它用于注入与当前http请求相关的对象(您可以在此处找到可注入实例的列表),并且您可以在实例字段和方法参数上使用它

在JAX-RS资源上使用@Stateless可以很好地防止web服务器为每个调用创建新的resource(就像使用@RequestScoped注释一样)。当使用@Stateless注释时,服务器将创建一个可配置的资源池。您还将从交易中获得好处。

最新更新