gpt4 book ai didi

java - JAX-RS (Jersey) ExceptionMapper - @Context 注入(inject)静态/单例类 - 它有效,但为什么呢?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:59:21 30 4
gpt4 key购买 nike

我有一个单实例类,实现了 ExceptionMapper。它不是静态类,但我知道它是一个只创建了单个实例的类(我检查过 - 构造函数只被调用一次)。

我的类使用@Context HttpServletRequest,我可以清楚地观察到当调用我的ExceptionMapper.toResponse() 方法时,@Context 'request' 参数具有与抛出异常的请求相关的值。

The doc says 这确实是设计支持的功能,它是通过使用“代理”来完成的。

我想知道这究竟是如何实现的——单个实例如何同时具有不同的成员变量值?

谢谢你,
股份公司

P.S.: 这是测试代码:

@Provider
public class MyExceptionMapper implements ExceptionMapper<Exception> {

public MyExceptionMapper() {
System.out.println("CTOR!!");
}

@Context HttpServletRequest req;

public static boolean done = false;
public Response toResponse(Exception ex) {
if (!done) {
done = true;
Thread.sleep(10000);
}
System.out.println(req.getRequestURI());
return null;
}
}

我的 REST 处理程序方法抛出异常,所以当我“并行”执行以下 2 个请求时(上面的 sleep 确保第一个在第二个到达时没有完成,恕我直言应该修改唯一的“请求”领域):

- http://localhost/app/one
- http://localhost/app/two

我的程序打印:

CTOR!
http://localhost/app/one
http://localhost/app/two

最佳答案

实现您观察到的效果的最简单方法是将注入(inject)的 HttpServletRequest 对象实际作为代理对象,真实 的线程感知委托(delegate)HttpServletRequest。当您在委托(delegate)上调用方法时,它们所做的只是查找正确的真实对象(例如,通过线程局部变量)并将调用传递给它。这种策略相对简单,而且由于它是一个接口(interface),我们绝对不必担心字段访问(这对于代理来说有点棘手)。

有几种不同的方法可以构造这样的代理对象。特别是,它可以通过直接实现 HttpServletRequest 接口(interface)来完成,或者可以通过 Java general dynamic proxy mechanism 更通用地完成。 (它可以为任何接口(interface)构造一个代理)。还有其他更复杂的可能性,例如运行时代码生成,但这里没有必要。 OTOH,如果 HttpServletRequest 被直接实现,我一点也不会感到惊讶;对于 JAX-RS 实现来说,这是一个有点重要的类……

关于java - JAX-RS (Jersey) ExceptionMapper - @Context 注入(inject)静态/单例类 - 它有效,但为什么呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17766072/

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