gpt4 book ai didi

jakarta-ee - JAX-RS 2 过滤器有哪些范围?

转载 作者:行者123 更新时间:2023-12-04 02:10:54 25 4
gpt4 key购买 nike

我正在使用 RestEasy 3.0.2,它是第一个 JAX-RS 2 实现之一,并在 Tomcat 7 中运行我的应用程序。我还通过 WELD 在我的应用程序中使用注入(inject),WELD 通过其 CDI 适配器与 RestEasy 集成.到目前为止一切正常。

现在,我编写了一个 ContainerRequestFilter 的实现,以在传入请求到达资源之前对其进行身份验证。 JAX-RS 标准规定,每个资源和每个其他使用 @Provider 注释进行注释的 JAX-RS 组件都可以进行注入(inject)。

这是我的过滤器实现的简化版本:

@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

@Inject
AuthenticationProvider authenticationProvider;

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
authenticationProvider.authenticate(requestContext);
}
}

注意:AuthenticationProvider@RequestScoped

通常,此解决方案有效。正在注入(inject)组件并按预期处理请求。

但我仍然怀疑过滤器的作用范围。如果它是应用程序范围的,那么这显然会导致确定性测试无法发现的“有趣”并发问题。

我查看了各种文档、指南和示例,但我没有发现任何使用过滤器注入(inject)或说明过滤器范围的内容。

最佳答案

对于 RestEasy,答案在 RestEasy documentation concerning CDI integration 中给出。 :

A CDI bean that does not explicitly define a scope is @Dependent scoped by default. This pseudo scope means that the bean adapts to the lifecycle of the bean it is injected into. Normal scopes (request, session, application) are more suitable for JAX-RS components as they designate component's lifecycle boundaries explicitly. Therefore, the resteasy-cdi module alters the default scoping in the following way:

If a JAX-RS root resource does not define a scope explicitly, it is bound to the Request scope.

If a JAX-RS Provider or javax.ws.rs.Application subclass does not define a scope explicitly, it is bound to the Application scope.

因此,使用@Provider 注释的 JAX-RS 过滤器是@ApplicationScoped。

该文档还指出,JAX-RS 提供程序可以通过向其添加适当的注释来与任何范围相关联。所以一般来说,JAX-RS 过滤器的范围是可以定制的。

重要的是要注意将@RequestScoped 对象注入(inject)@ApplicationScoped 过滤器是安全的。这是因为 CDI 不注入(inject)对实际对象的引用,而是对代理的引用。在代理上调用方法时,将在幕后为每个请求使用一个单独的对象实例。

这里是根据WELD documentation :

4.9. Client proxies

Clients of an injected bean do not usually hold a direct reference to a bean instance, unless the bean is a dependent object (scope @Dependent).

Imagine that a bean bound to the application scope held a direct reference to a bean bound to the request scope. The application-scoped bean is shared between many different requests. However, each request should see a different instance of the request scoped bean—the current one!

...

Therefore, unless a bean has the default scope @Dependent, the container must indirect all injected references to the bean through a proxy object. This client proxy is responsible for ensuring that the bean instance that receives a method invocation is the instance that is associated with the current context. The client proxy also allows beans bound to contexts such as the session context to be serialized to disk without recursively serializing other injected beans.

我使用以下代码来验证这一点(假设 entityManager 在示例中生成为 @RequestScoped):

@Provider
public class OtherTestFilter implements ContainerRequestFilter {

@Inject
EntityManager entityManager;

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
Session session = (Session) entityManager.getDelegate();
System.out.println(session.hashCode());
}
}

这为过滤器处理的每个请求提供了不同的session 哈希值。所以理论和实践在这里是一致的。

关于jakarta-ee - JAX-RS 2 过滤器有哪些范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17897187/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com