【问题标题】:Java dynamic proxy questionsJava 动态代理问题
【发布时间】:2010-04-14 10:05:15
【问题描述】:

1.动态代理实例是目标类的子类吗? java文档说代理实例实现了“接口列表”,没有说子类化,但是通过调试,我看到代理实例确实继承了目标类属性。“接口列表”是什么意思?我可以排除目标类实现的那些接口吗?

2.我可以在代理实例上调用目标类特定的方法吗?

3。 我认为动态代理是接口方法调用代理,而不是目标类代理,对吗(我被休眠代理对象概念深深感染)?

【问题讨论】:

  • Hibernate使用CGLIB来代理类,java.lang.reflect.Proxy只能代理接口。 CGLIB 创建了一个子类来代理一个类...

标签: java


【解决方案1】:

如果您谈论的是java.lang.reflect.Proxy 类:一般来说,没有“目标类”这样的东西。

代理是constructed,通过指定代理对象将实现的接口列表,以及一个调用处理程序,其invoke()方法的所有方法调用代理将被转发到。调用处理程序可以对它们做任何事情,包括将它们转发到它持有引用的“目标类”实例。

【讨论】:

  • @Michael Borgwardt:谢谢,Micheal。正如您所引用的,“目标类”是调用处理程序引用的类。调用处理程序是否必须持有这种引用? InvocationHandler的invoke方法里面的method.invoke()一定要接收到代理接口的实现吗?
  • 如果我们没有将代理接口的实现传递给method.invoke(),那么在我们创建的代理实例上调用一个空白实现是没有意义的。如果我们传递这个引用,为什么不直接调用实例方法?
  • @Tony:不,这个“目标类”是一个实现细节,而不是一般概念。调用处理程序绝对可以做任何事情,而不仅仅是转发调用。一个典型的例子是接口的通用实现,它只包含匹配的 getter 和 setter,它们将属性存储在 HashMap 中。简单地转接电话而不做任何其他事情确实是毫无意义的。但是如果你在转发的基础上再做点别的,这是一种实现 AOP 的方式。
【解决方案2】:
  1. 我想你误会了。传递给getProxyClass() 的每个Class 对象都必须是接口的类对象,而不是具体类。所以String.class 不是一个有效的参数,但List.class 是。正如它所说的“接口数组中的所有类对象都必须表示接口,而不是类或原始类型”。因此子类是不相关的。

  2. 否(因为类在这里不相关,只有接口)。如果您需要访问它们,请添加一个接口。

  3. 正确。

【讨论】: