论坛首页 入门技术论坛

Java动态代理的设计是否有缺陷??

浏览 14611 次
该帖已经被评为新手帖
作者 正文
   发表时间:2010-04-23  
xyz20003 写道
Agrael 写道


返回代理的话基本是不能用的,也只有返回目标对象才可以。



为何返回代理不能用呢?为什么只能返回目标哦对象呢?


直接使用第一个参数那个proxy,是会一直递归调用下去的。
当然,你返回那个proxy拿去做类型信息分析,还是可以用到的。
返回目标对象的作用就是可以在上面直接或者反射调用方法。
0 请登录后投票
   发表时间: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



构造函数传进去。
0 请登录后投票
   发表时间:2010-04-23  
构造函数传进去??

这个InvocationHandler如果传入知道特定的构造函数的话,那。。。。。。


如果提供setTarget的方法的话,InvocationHandler知道的也就是个Object

如果不用setTarget,而是通过反射,得到构造方法的函数的话,那个InvocationHandler这个切面,就和某个类紧密的结合了。 。。。。
0 请登录后投票
   发表时间:2010-04-23  
xiaolongfeixiang 写道
构造函数传进去??

这个InvocationHandler如果传入知道特定的构造函数的话,那。。。。。。


如果提供setTarget的方法的话,InvocationHandler知道的也就是个Object

如果不用setTarget,而是通过反射,得到构造方法的函数的话,那个InvocationHandler这个切面,就和某个类紧密的结合了。 。。。。

用Object。
private Object t;

public Xxxxxx(Object t){
    this.t = t;
}
0 请登录后投票
   发表时间:2010-04-23  
Agrael 写道

用Object。
private Object t;

public Xxxxxx(Object t){
    this.t = t;
}


似乎和setTarget类似。 觉得又像回到原地了。。
0 请登录后投票
   发表时间:2010-04-23  
我也有楼主同样的疑问,那个invoke方法的第一个参数proxy总感觉用不到。
0 请登录后投票
   发表时间: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;
	}
}
0 请登录后投票
   发表时间: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参数。
0 请登录后投票
   发表时间:2010-04-23  
看的有点迷糊。。。
1、既然你proxy里有类型信息了,你还有什么干不了得呢?为什么还要setTarget
2、既然proxy只是提供类型信息,那么他可能只是RealInterface而不是RealObject?那你去掉newInstance()难道不应该报错。。而且你为什么会要去newInstance()
0 请登录后投票
   发表时间:2010-04-23  
谁说target是必须的?
动态代理只是为一个接口产生一个动态的实例,这个实例可以调用其他对象的方法,如你所说的target,也可以不调用。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics