JAX-RS:Stateless、Singleton、RequestScoped 混淆

JAX-RS: Stateless, Singleton, RequestScoped confusion

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

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

我应该使用哪个注解?

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

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

我的意思是,我看到这个 应用于参数,也在 class 字段中

@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...
    }

}

我将如何进行?

关于您的第一个问题(托管 bean 作用域),我认为不应使用作用域注释,因为 java-ee 容器将根据 Jax- rs 注释。

然而 the guys from ibm seems to have a different idea of the question 并陈述以下内容

Best practice

Add specific lifecycle scopes to any JAX-RS root resource and provider classes that exist in your application, in a JCDI-enabled archive. For JAX-RS resource classes with an @javax.ws.rs.Path annotation, you can use @javax.enterprise.context.RequestScoped. For javax.ws.rs.core.Application sub-classes and @javax.ws.rs.ext.Provider annotated classes, you must use @javax.enterprise.context.ApplicationScoped.

关于@Context注解,它用于注入与当前http请求相关的对象(你可以找到一个list of injectable instances here),你可以在实例字段和方法参数上使用它

无需在 JAX-RS 资源中使用任何 EJB 或 CDI 注释 class - 除非您想在相同的资源中使用 EJB 或 CDI 功能 class。

如果要将任何CDI bean注入到资源classes中,那么资源class本身必须是一个CDI bean,所以你应该添加一个范围注解,最好是@javax.enterprise.context.RequestScoped.

如果您使用像 @Stateless 这样的 EJB 注释,注入也将起作用,因为 EJB 也是 CDI bean(但反之则不然)。但是,无状态 bean 具有不同的生命周期,默认情况下它是事务性的。

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

背景:

EJB 对于大多数用途来说有点过时了。它们先出现,在 JAX-RS 和 CDI 之前,但如今,CDI 被视为 Java EE/Jakarta EE 中的统一依赖注入机制,并且正在更新较旧的规范以获得更多与 CDI 紧密结合。

在 JAX-RS 资源上使用 @Stateless 可以很好地防止 Web 服务器为每次调用创建新资源(因为它是使用 @RequestScoped 注释完成的)。 使用 @Stateless 注释时,服务器将创建一个可配置的资源池。 您还将获得交易收益。