Java 动态代理的问题

4

1. 动态代理实例是否会子类化目标类? Java文档表示,代理实例实现了“一组接口”,没有提到子类化,但是通过调试,我发现代理实例确实继承了目标类的属性。"一组接口"是什么意思?我能排除目标类实现的那些接口吗?

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

3. 我认为动态代理是一个接口方法调用代理而不是目标类代理,对吗(我深受Hibernate代理对象概念的影响)?


Hibernate使用CGLIB来代理类,而java.lang.reflect.Proxy只能代理接口。而CGLIB会创建一个子类来代理一个类... - pgras
2个回答

6
如果您在谈论java.lang.reflect.Proxy类:一般情况下不存在所谓的“目标类”。
代理是通过指定代理对象将实现的接口列表和一个调用处理程序来构造的,代理上所有方法调用都将转发到其invoke()方法的调用处理程序。调用处理程序可以对它们执行任何操作,包括将它们转发到它持有引用的“目标类”实例。

@Michael Borgwardt:谢谢,Michael。正如你引用的那样,“目标类”是调用处理程序所持有引用的类。调用处理程序必须持有这种引用吗?在InvocationHandler的invoke方法中的method.invoke()必须接收代理接口的实现吗? - Sawyer
如果我们没有将代理接口的实现传递给method.invoke()方法,那么在我们创建的代理实例上调用一个空的实现是毫无意义的。如果我们传递了这个引用,那为什么不直接调用实例方法呢? - Sawyer
@Tony:不,这个“目标类”是实现细节,而不是通用概念。调用处理程序可以做任何事情,远不止转发调用。一个典型的例子是接口的通用实现,该接口仅由匹配的getter和setter组成,并将属性存储在HashMap中。简单地转发调用而不做其他任何事情确实是毫无意义的。但是,如果您在转发之上做其他事情,那么它就是实现AOP的一种方式。 - Michael Borgwardt

1
  1. 我想你误解了。每个传递给 getProxyClass()Class 对象必须是接口的类对象,而不是具体类的类对象。所以,String.class 不是一个有效的参数,但 List.class 是。正如它所说的"接口数组中的所有 Class 对象必须表示接口,而不是类或原始类型"。因此,子类是无关紧要的。

  2. 不行(因为这里与类无关,只涉及接口)。如果您需要访问它们,添加一个接口即可。

  3. 正确。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接