我正在尝试用Java学习动态代理。
我知道它们是如何工作的但是我找不到解决我的问题的方法:给定一个接口及其实现方法a(),b()和c()嵌套到另一个(让我们说a()调用b()调用c()),我想代理我的对象来记录对方法的EACH调用。
所以我编写我的InvocationHandler,例如invoke()方法在执行之前打印一个日志行。
但是当我调用proxy.a()时,只会记录方法a()的调用,而不是整个方法链。
我错过了什么?代理的目标是否必须是代理本身?
答案 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)
,并获得预期的结果。