posts - 82, comments - 269, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

动态代理的一些思考和疑问:(疑问还没解决)
在Java中有一个动态代理技术,主要通过Proxy,InvocationHandler和Method,这三个类(接口)来实现.但是有如下一个问题不太明白,希望高手解惑.

我查看了几个例子,它们实现InvocationHandler这个接口时,都通过构造函数传递进去了,实际被代理的对象,然后在实现的方法中通过method.invoke(obj,args);obj为构造函数传递进来的对象.

比如下面的例子:
public class Handler implements InvocationHandler {

 MethodInterface delegate;

 public Handler(MethodInterface delegate) {
  this.delegate = delegate;
 }

 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  if (method.getName().equals("say")) {
   System.out.print("I have get it");
  }
  return method.invoke(this.delegate, args); 
 }

}

函数invoke()传递进去的第一个参数proxy就没有被使用到,但同样实现了动态代理的效果,后面参考文献中的例子也是的,难道是这第一个参数就是多余的,如果是这样的话,就是Sun设置失误了 ^__^.

sun的文档是这样解释这个参数的:proxy - the proxy instance that the method was invoked on.但这个参数有什么用的,如果不传递他进来,会有什么不便呢.


有没有人能明白这是怎么回事,或者是写个示例代码,讲讲这个第一个参数是干嘛用的?

 

 

注:附两个完整的动态代理的例子
http://blog.csdn.net/hsyj_0001/archive/2006/04/02/647488.aspx
http://www.java2s.com/Code/Java/Development-Class/Demonstratesadynamicproxy.htm


评论

# re: 动态代理的一些思考和疑问:(疑问还没解决)  回复  更多评论   

2006-11-14 00:33 by kafka0102
实际使用的代理对象应该通过Proxy.newProxyInstance这样的方法实现,而代理对象调用的就是继承了InvocationHandler的类的public Object invoke(Object proxy, Method method, Object[] args)方法,这里的Object proxy应该就是代理对象本身。如果你的method.invoke(this.delegate, args); 改成method.invoke(proxy, args);将出现不断的循环。


# re: 动态代理的一些思考和疑问:(疑问还没解决)  回复  更多评论   

2006-11-14 09:39 by itspy
@kafka0102

楼上是高手!

是的,是出现了不断的循环,这个我已经测试过了,并且循环一定次数之后就出现了异常。

如果是这样的话,方法public Object invoke(Object proxy, Method method, Object[] args)

传递进来的proxy参数有什么用?难道是sun设计错了?

# re: 动态代理的一些思考和疑问:(疑问还没解决)  回复  更多评论   

2006-11-14 11:03 by yubaojian0616
你没有明白动态代理类的作用! 如果你返回 method.invoke(this.delegate, args); 他会继续调用invoke方法 然后继续返回 所以出现了死循环! 如果你没有需要在代理的内容应该返回null,如果有就返回代理的对象

# re: 动态代理的一些思考和疑问:(疑问还没解决)  回复  更多评论   

2006-11-14 11:19 by itspy
@yubaojian0616
谢谢你的回复,你可能刚好弄反了

method.invoke(proxy, args);这种方法会形成死循环


method.invoke(this.delegate, args); 这种是正确的调用,文章最后有两个参考引用,都是使用这种方式。


对于这点,你楼上的kafka0102就说的很对,你可能刚好说反了,或者是你理解上和我一样,有不明白的地方。不信你可以写测试程序去测试一下。或者是直接把引文里面的例子弄下来测试。



# re: 动态代理的一些思考和疑问:(疑问还没解决)  回复  更多评论   

2012-08-21 21:47 by chaisencs
你去看一下这个类RemoteObjectInvocationHandler的源代码,就知道参数proxy其实是有用的

只有注册用户登录后才能发表评论。


网站导航: