【问题标题】:Dynamic Proxy: how to handle nested method calls动态代理:如何处理嵌套方法调用
【发布时间】:2012-02-23 11:19:50
【问题描述】:

我正在尝试学习 Java 中的动态代理。

我知道它们是如何工作的,但我找不到解决我的问题的方法:给定一个接口及其实现方法 a()、b() 和 c() 嵌套在另一个中(比如说 a()调用 b() 调用 c()),我想代理我的对象来记录对方法的每次调用。

所以我编写了我的 InvocationHandler 代码,例如 invoke() 方法在执行之前打印了一个日志行。

但是当我调用 proxy.a() 时,只记录对方法 a() 的调用,而不是整个方法链。

我错过了什么?代理的目标必须是代理本身吗?

【问题讨论】:

    标签: java proxy nested invocationhandler


    【解决方案1】:

    好吧,对象本身并不知道它正在被代理,所以当 a() 调用 b() 时,它将是一个正常的“内部对象”调用。

    如果代理的目标是代理本身,就会出现循环。

    如果确实需要,解决此问题的一种方法是向目标对象引入一个委托,并使用代理或将其自身设置为委托。奇怪,但可能有效。不过要注意循环。

    【讨论】:

    • 你的意思是使用代理的 obj 而不是调用处理程序中的 obj 吗?我试图让调用处理程序扩展我的对象的类并将调用方法应用于同一个调用处理程序实例(method.invoke(this,args),我认为它会假装是对象,但每个方法调用都由代理过滤),但又一次失败了。
    【解决方案2】:

    这是因为,当您从测试代码调用proxy.a() 时,您的最终a() 方法不是调用proxy.b(),而是直接调用self 实例b()

    作为一种解决方法,您可以重载每个方法并传递一个委托实例。假设类名MyClass,接口名MyInterface:

    void a() {
       //to keep the non-proxy working, the default method have to pass the 
       //self intance
       a(this);
    }
    void a(MyInterface target) {
       target.b(target);
    }
    
    void b() {
       b(this);
    }
    void b(MyInterface target) {
       target.c(target);
    }
    void c() {
       c(this);
    }
    void c(MyInterface target) {
       //do whatever
    }
    

    然后,从您的测试代码中,您将能够调用proxy.a(proxy),并获得预期的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-01
      • 1970-01-01
      • 2021-07-21
      • 2012-09-14
      • 2013-06-10
      • 2016-10-15
      • 1970-01-01
      相关资源
      最近更新 更多