[英]JAX-RS (Jersey) ExceptionMapper - @Context injection into static/singleton class - it works, but why?
我有一个单实例类,实现ExceptionMapper。 它不是一个静态类,但它是一个我只知道创建单个实例的类(我检查过-构造函数仅被调用一次)。
我的类使用@Context HttpServletRequest ,并且我可以清楚地观察到,当调用ExceptionMapper.toResponse()方法时, @ Context的“ request”参数具有与引发异常的请求相关的值。
该文档说,这确实是受设计支持的功能,并且可以通过使用“代理”来完成。
我想知道这是如何实现的-单个实例如何同时具有不同的成员变量值?
谢谢,
AG
PS:这是测试代码:
@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处理程序方法引发异常,因此当我“并行”执行以下两个请求时(上面的睡眠可确保在第二个请求到达时第一个请求未完成,恕我直言,IMHO应该修改一个“ req”字段):
- http://localhost/app/one
- http://localhost/app/two
我的程序打印:
CTOR!
http://localhost/app/one
http://localhost/app/two
实现所观察到的效果的最简单方法是,将注入的HttpServletRequest
对象实际用作代理对象,即真正的 HttpServletRequest
的线程感知委托。 当您在委托上调用方法时,它们所做的就是查找正确的真实对象(例如,通过线程局部变量)并将调用传递给该对象。 该策略相对来说比较容易实现,并且因为它是一个接口,所以我们绝对不必担心字段访问(代理很麻烦)。
有几种不同的方法来构造这样的代理对象。 特别是,它可以通过直接实现HttpServletRequest
接口来完成,也可以通过Java 通用动态代理机制 (可以为任何接口构造代理)更一般地完成。 还有其他更复杂的可能性,例如运行时代码生成,但是这里没有必要。 OTOH,如果直接实现HttpServletRequest
,我不会感到惊讶。 对于JAX-RS实现来说,这是一个非常重要的类……
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.