在 Jersey 2 中调用代理对象的包私有方法的奇怪行为

Strange behavior calling package-private method of proxied object in Jersey 2

关注class

public class MaskHolder {

    private Mask mask;
    private UUID id = UUID.randomUUID()

    void store() {
        System.out.println(id);
    }

    public void get() {
        System.out.println(id);
    }

}

像这样绑定到HK2

bind(MaskHolder.class).to(MaskHolder.class)
            .proxy(true).proxyForSameScope(false).in(RequestScoped.class);

使用@Context 注入 bean 的代理行为与 public 方法的预期行为相同,但也执行 package-private 方法。问题是 package-private 方法不会触发 MethodInterceptor 所以它实际上没有达到 get() 所达到的相同实例。 问题是代理将包私有方法调用转发到的 "default" 实例是什么。调用 get() 方法时,我会根据不同的请求到达不同的实例,但调用 store 方法每次都会在同一个实例中结束,因此它的行为类似于单例。

还有一件事我没有提到 - 行为像单例的代理被注入到 JacksonJsonProvider 子类中。据我所知,JacksonJsonProvider 的这个子类在 Jersey 中只创建了一次,因此注入其中的代理实例在请求之间不会改变。

Proxy 基本上是 MaskHolder 的人工子类,在 public 方法上有拦截器,但它基本上是 MaskHolder 和它的 UUID 字段。因此,如果拦截器不提供 RequestScope bean,我们将访问 "parent" MaskHolder。而且因为代理实例只注入一次 JacksonJsonProvider 它在请求之间是相同的。

MaskHolder 注入资源会导致跨请求的代理实例不同(不同的 UUID)。