Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 动态代理:如何处理嵌套方法调用_Java_Proxy_Nested_Invocationhandler - Fatal编程技术网

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

Java 动态代理:如何处理嵌套方法调用,java,proxy,nested,invocationhandler,Java,Proxy,Nested,Invocationhandler,我试图学习Java中的动态代理 我知道它们是如何工作的,但我找不到解决问题的方法:给定一个接口及其实现,其中方法a()、b()和c()相互嵌套(假设a()调用b(),后者调用c()),我希望代理我的对象来记录对方法的每次调用 因此,我编写了调用处理程序,例如invoke()方法,在执行之前打印日志行 但是当我调用proxy.a()时,只记录方法a()的调用,而不记录整个方法链 我错过了什么?代理的目标必须是代理本身吗?嗯,对象本身不知道它正在被代理,所以当a()调用b()时,它将是一个正常的“对

我试图学习Java中的动态代理

我知道它们是如何工作的,但我找不到解决问题的方法:给定一个接口及其实现,其中方法a()、b()和c()相互嵌套(假设a()调用b(),后者调用c()),我希望代理我的对象来记录对方法的每次调用

因此,我编写了调用处理程序,例如invoke()方法,在执行之前打印日志行

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


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

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

如果代理的目标是代理本身,则将有一个循环


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

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

如果代理的目标是代理本身,则将有一个循环


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

这是因为,当您从测试代码调用
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)
,并获得预期的结果。

这是因为,当您从测试代码中调用
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)
,并获得预期结果。

您的意思是在调用处理程序中使用代理obj而不是obj吗?我尝试让调用处理程序扩展我的对象的类,并在同一个invochandler实例(method.invoke(this,args))上应用invoke方法,我认为它会假装是对象,但每个方法调用都会被代理过滤,但是它再次失败了。你是说在调用处理程序中使用代理的obj而不是obj吗?相反,我尝试让调用处理程序扩展我的对象的类,并将invoke方法应用于同一invochandler实例(method.invoke(this,args),我认为它会假装是对象,但每个方法调用都会被代理过滤掉),但再次失败。