我有一个单实例类,实现 ExceptionMapper。它不是一个静态类,但我知道它只创建了一个实例(我检查过 - 构造函数仅被调用一次)。
我的班级使用@Context HttpServletRequest,我可以清楚地观察到,当我的ExceptionMapper.toResponse()方法被调用时,@Context'请求'参数具有与引发异常的请求相关的值。
医生说 https://jersey.github.io/documentation/latest/jaxrs-resources.html#d0e2760这确实是设计支持的功能,并且是通过使用“代理”来完成的。
我想知道这是如何实现的 - 单个实例如何同时具有不同的成员变量值?
谢谢你,
AG
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 个请求时(上面的睡眠确保当第二个请求到达时第一个请求尚未完成,恕我直言,应该修改唯一的“req”字段):
- http://localhost/app/one
- http://localhost/app/two
我的程序打印:
CTOR!
http://localhost/app/one
http://localhost/app/two
实现您观察到的效果的最简单方法是注射HttpServletRequest
对象实际上是一个代理对象,一个线程感知的委托real HttpServletRequest
。当您调用委托上的方法时,它们所做的就是查找正确的真实对象(例如,通过线程局部变量)并将调用传递到该对象上。这种策略相对简单,而且由于它是一个接口,我们绝对不必担心字段访问(这对于代理来说相当棘手)。
有几种不同的方法可以构造这样的代理对象。特别是,可以通过直接实施HttpServletRequest
接口,或者可以通过 Java 更通用地完成通用动态代理机制 http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html(可以为任何接口构造代理)。还有其他更复杂的可能性,例如运行时代码生成,但它们在这里是不必要的。 OTOH,如果HttpServletRequest
直接实施;对于 JAX-RS 实现来说,它是一个相当重要的类……
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)