JAX-RS:无状态,单例,RequestScoped混乱

时间:2019-02-05 09:29:46

标签: java jax-rs cdi

我已经看到过多次配置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...
    }

}

我将如何进行?

3 个答案:

答案 0 :(得分:2)

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

如果要将任何CDI bean注入资源类,则资源类必须是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集成。

答案 1 :(得分:1)

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

但是the guys from ibm seems to have a different idea of the question并声明以下内容

  

最佳做法

     

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

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

答案 2 :(得分:0)

在JAX-RS资源上使用@Stateless可以防止Web服务器为每个调用创建新的资源(如使用@RequestScoped批注那样)。 使用@Stateless批注时,服务器将创建可配置的资源池。 您还将获得交易的好处。