锁定老帖子 主题:Java动态代理的设计是否有缺陷??
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-04-23
xyz20003 写道 Agrael 写道 返回代理的话基本是不能用的,也只有返回目标对象才可以。 为何返回代理不能用呢?为什么只能返回目标哦对象呢? 直接使用第一个参数那个proxy,是会一直递归调用下去的。 当然,你返回那个proxy拿去做类型信息分析,还是可以用到的。 返回目标对象的作用就是可以在上面直接或者反射调用方法。 |
|
返回顶楼 | |
发表时间:2010-04-23
xiaolongfeixiang 写道 Agrael 写道 纠正下我之前说的。反射调用目标对象方法的信息还是得从目标对象获取。proxy提供的仅仅只能作为代理分析,用来调用目标对象方法的话,我如果没记错应该会报错。
你说的对,直接在proxy上调用目标对象的方法是会报错的。 但是,我这样做也会错的: public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (args != null) { for (Object obj : args) { System.out.println("参数" + obj); } } System.out.println("Before"); //Object result = method.invoke(target, args); // 这行会报错 Object obj = proxy.getClass().newInstance(); Object result = method.invoke(obj, args); System.out.println("After"); return result; } 输出是: 我又迷糊了。不通过seTarget的话,如何进行下去? 引用 Before Exception in thread "main" java.lang.reflect.UndeclaredThrowableException at $Proxy0.sayHello(Unknown Source) at study.proxy.ProxyBasicDemo.main(ProxyBasicDemo.java:23) Caused by: java.lang.InstantiationException: $Proxy0 at java.lang.Class.newInstance0(Unknown Source) at java.lang.Class.newInstance(Unknown Source) at study.proxy.MyInterceptor.invoke(MyInterceptor.java:27) ... 2 more 构造函数传进去。 |
|
返回顶楼 | |
发表时间:2010-04-23
构造函数传进去??
这个InvocationHandler如果传入知道特定的构造函数的话,那。。。。。。 如果提供setTarget的方法的话,InvocationHandler知道的也就是个Object 如果不用setTarget,而是通过反射,得到构造方法的函数的话,那个InvocationHandler这个切面,就和某个类紧密的结合了。 。。。。 |
|
返回顶楼 | |
发表时间:2010-04-23
xiaolongfeixiang 写道 构造函数传进去??
这个InvocationHandler如果传入知道特定的构造函数的话,那。。。。。。 如果提供setTarget的方法的话,InvocationHandler知道的也就是个Object 如果不用setTarget,而是通过反射,得到构造方法的函数的话,那个InvocationHandler这个切面,就和某个类紧密的结合了。 。。。。 用Object。 private Object t; public Xxxxxx(Object t){ this.t = t; } |
|
返回顶楼 | |
发表时间:2010-04-23
Agrael 写道 用Object。 private Object t; public Xxxxxx(Object t){ this.t = t; } 似乎和setTarget类似。 觉得又像回到原地了。。 |
|
返回顶楼 | |
发表时间:2010-04-23
我也有楼主同样的疑问,那个invoke方法的第一个参数proxy总感觉用不到。
|
|
返回顶楼 | |
发表时间:2010-04-23
andot 写道 我也有楼主同样的疑问,那个invoke方法的第一个参数proxy总感觉用不到。
这样包装一下,不知道会不会好点。 import java.lang.reflect.InvocationHandler; public abstract class InvocationAdapter implements InvocationHandler{ protected Object realTarget; protected void setRealTarget(Object realTarget) { this.realTarget = realTarget; } } |
|
返回顶楼 | |
发表时间:2010-04-23
最后修改:2010-04-23
Target你用构造方法传入就可以啦,不需要加什么方法。用构造方法还可以传入更多参数,还可以指定各种类型,比一个固定的传入Object参数的方法好的多。例如,下面是我写的一个实际程序中的写法:
public class HproseInvocationHandler implements InvocationHandler { private HproseInvoker client; private String ns; public HproseInvocationHandler(HproseInvoker client, String ns) { this.client = client; this.ns = ns; } ... } 不过我跟你一样,在后面的invoke方法中,没有用到proxy参数。 |
|
返回顶楼 | |
发表时间:2010-04-23
看的有点迷糊。。。
1、既然你proxy里有类型信息了,你还有什么干不了得呢?为什么还要setTarget 2、既然proxy只是提供类型信息,那么他可能只是RealInterface而不是RealObject?那你去掉newInstance()难道不应该报错。。而且你为什么会要去newInstance() |
|
返回顶楼 | |
发表时间:2010-04-23
谁说target是必须的?
动态代理只是为一个接口产生一个动态的实例,这个实例可以调用其他对象的方法,如你所说的target,也可以不调用。 |
|
返回顶楼 | |