动态代理:如何处理嵌套方法调用

时间:2012-02-23 11:19:50

标签: java proxy nested invocationhandler

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

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

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

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

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

2 个答案:

答案 0 :(得分:2)

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

如果代理的目标是代理本身,那么你将有一个循环。

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

答案 1 :(得分:2)

这是因为,从您的测试代码中调用proxy.a(),您的最终a()方法不会调用proxy.b(),而是直接调用自我实例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),并获得预期的结果。