JAX-RS(泽西岛)ExceptionMapper-@Context注入到static/singleton类中-它可以工作,但是为什么呢? [英] JAX-RS (Jersey) ExceptionMapper - @Context injection into static/singleton class - it works, but why?

查看:123
本文介绍了JAX-RS(泽西岛)ExceptionMapper-@Context注入到static/singleton类中-它可以工作,但是为什么呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a single-instance class, implementing ExceptionMapper. It's not a static class, but it's a class for which I know only single instance is created (I checked - constructor is called only once).

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

My class uses @Context HttpServletRequest, and I can clearly observe that when my ExceptionMapper.toResponse() method is called, the @Context 'request' parameter has a value which is relevant for a request where the exception is thrown.

医生说 这确实是受设计支持的功能,并且可以通过使用代理"来完成.

The doc says this is indeed by-design supported feature and that it's done by using "proxies".

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

I wonder how exactly this is implemented - how a single instance can have different member variable values simultaneously?

谢谢你,
AG

Thank you,
AG

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

P.S.: here's the test code:

@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个请求时(上面的睡眠可确保在第二个请求到达时第一个请求未完成,恕我直言,IMHO应该修改唯一的"req"字段):

My REST handler method throws exception, so when I execute the following 2 requests "in parallel" (the sleep above makes sure first one is not finished when second one arrives and IMHO should modify the one-and-only 'req' field):

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

我的程序打印:

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

推荐答案

达到您观察到的效果的最简单方法是,将注入的HttpServletRequest对象实际用作代理对象,即 real HttpServletRequest.当您在委托上调用方法时,它们所做的只是查找正确的真实对象(例如,通过线程局部变量)并将调用传递给该对象.该策略相对容易实现,并且由于它是一个接口,我们绝对不必担心字段访问(代理很麻烦).

The simplest method of achieving the effect you observe is for the injected HttpServletRequest object to actually be a proxy object, a thread-aware delegate for the real HttpServletRequest. When you call methods on the delegate, all they do is look up the correct real object (e.g., via a thread local variable) and pass the call onto that. This strategy is relatively simple to get right, and as it is an interface we definitely don't have to worry about field accesses (which are quite a bit trickier to proxy for).

有几种不同的方法来构造这样的代理对象.特别是,它可以通过直接实现HttpServletRequest接口来完成,也可以通过Java

There's a few different ways to construct such a proxy object. In particular, it could be done by directly implementing the HttpServletRequest interface, or it could be done more generically via the Java general dynamic proxy mechanism (which can construct a proxy for any interface). There are other more elaborate possibilities such as runtime code generation, but they're unnecessary here. OTOH, I wouldn't be at all surprised if HttpServletRequest was directly implemented; it's a somewhat important class for a JAX-RS implementation…

这篇关于JAX-RS(泽西岛)ExceptionMapper-@Context注入到static/singleton类中-它可以工作,但是为什么呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆