繁体   English   中英

JAX-RS(Jersey)ExceptionMapper-将@Context注入到static / singleton类中-它可以工作,但是为什么呢?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM