JAX-RS:Stateless、Singleton、RequestScoped 混淆
JAX-RS: Stateless, Singleton, RequestScoped confusion
我见过很多次 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
注释。
我的意思是,我看到这个 应用于参数,也在 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
注释时,服务器将创建一个可配置的资源池。
您还将获得交易收益。
我见过很多次 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
注释。
我的意思是,我看到这个 应用于参数,也在 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
注释时,服务器将创建一个可配置的资源池。
您还将获得交易收益。