黑马程序员技术交流社区
标题:
动态代理
[打印本页]
作者:
gzbbxu
时间:
2013-6-25 09:57
标题:
动态代理
本帖最后由 孙百鑫 于 2013-6-30 08:17 编辑
动态代理的Proxy.newProxyInstance到底返回的是什么东西啊?还有InvocationHandler的子类,到底是干啥的?表示不理解。。还有,就是重写的方法invoke方法中,Object proxy这个参数到底该怎么理解?好像没有用到吧?有什么作用呢?
作者:
wangpan
时间:
2013-6-25 11:52
首先是什么时候用到代理?
就是在已有一个类的情况下,你需要在这个类的方法上,添加其他的功能,那么你就可以用到代理。
你可以用另外一个方法(其实就是InvocationHandler的invoke方法)把目标类的方法封装起来,然后再这个方法的前后,添加上代码实现你想实现的功能,其实这就是InvocationHandler要实现的功能。
Proxy.newProxyInstance方法返回的就是一个指定接口的代理类实例。
举个例子应该更清楚一些:
<P> </P>
复制代码
proxy3.add("zxx");//这行代码有三个元素,proxy3、add、"zxx"。
执行这句代码的时候,proxy3传给InvocationHandler的invoke方法的第一个参数Object proxy,
add传给第二个参数Method method,"zxx"传给第三个参数Object[] args。这样InvocationHandler才会知道,是哪个代理调用的哪个方法,使用的是什么参数。
整段代码就相当于在ArrayList的add方法的前后加了①②③这三行代码,InvocationHandler的invoke方法返回的还是method.invoke(target, args);的返回值。
至于你说invoke的Object proxy参数没用到,因为这个invoke方法不是显示的去调用,我想应该是里面封装了吧。
作者:
wangpan
时间:
2013-6-25 11:55
代码没上去,不好意思。
首先是什么时候用到代理?
就是在已有一个类的情况下,你需要在这个类的方法上,添加其他的功能,那么你就可以用到代理。
你可以用另外一个方法(其实就是InvocationHandler的invoke方法)把目标类的方法封装起来,然后再这个方法的前后,添加上代码实现你想实现的功能,其实这就是InvocationHandler要实现的功能。
Proxy.newProxyInstance方法返回的就是一个指定接口的代理类实例。
举个例子应该更清楚一些:
<P>Collection proxy3 =(Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),
new Class[]{Collection.class},
new InvocationHandler(){
ArrayList target = new ArrayList();
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
long beginTime = System.currentTimeMillis();//①</P>
<P>Object retVal = method.invoke(target, args);
long endTime = System.currentTimeMillis();//②
System.out.println(method.getName()+" running time is "+(endTime-beginTime));//③
return retVal;
}
});
//执行一次proxy3的方法,就会执行一次InvocationHandler的invoke方法
proxy3.add("zxx");//返回值就是invoke方法的返回值</P>
复制代码
proxy3.add("zxx");//这行代码有三个元素,proxy3、add、"zxx"。
执行这句代码的时候,proxy3传给InvocationHandler的invoke方法的第一个参数Object proxy,
add传给第二个参数Method method,"zxx"传给第三个参数Object[] args。这样InvocationHandler才会知道,是哪个代理调用的哪个方法,使用的是什么参数。
整段代码就相当于在ArrayList的add方法的前后加了①②③这三行代码,InvocationHandler的invoke方法返回的还是method.invoke(target, args);的返回值。
至于你说invoke的Object proxy参数没用到,因为这个invoke方法不是显示的去调用,我想应该是里面封装了吧。
作者:
HM朱蛟
时间:
2013-6-26 04:24
我的愚见:
代理这种设计模式我感觉有点类似于装饰设计模式,只不过没有接收一个对象罢了。
它的存在是为了解决AOP的问题,AOP是啥呢?AOP就是将各种交叉业务模块化的一个过程。那么问题又来了,你每个类都去写代理岂不是累死人,假设有1000个类你岂不是要写1000个代理?
动态代理说:“不要怕,还有我”。那么啥是动态代理呢?动态代理就是为了完善代理的一种手段,它可以生成一个类,这个类是作为一个目标类的代理类的。这就是动态类。
我们通常所说的动态代理实际上都是在构建一个动态类实例。ok,那么怎么构建?那么invocationhandler这玩意就用上了,这玩意名字挺长,你也不用去查字典它叫啥意思,你就记住invocationhandler它是一个接口,就是在构建一个动态类实例时需要接受的一个参数罢了(它的实现类)。然而这个invocationhandler参数自身又有3个参数,这3个参数分别是方法,目标类,参数。方法和参数是系统自己传递的,而目标类是我们传递的。
我们在构建一个动态类实例的时候有三种方式。一种是老老实实的获取构造器,然后newInstance,然后newinstance的时候传入一个事先构建好的invocationhandler实现类。第二种方法就是第一种方法的匿名内部类形式,第三种方法就是我楼上那种方法。
作者:
郭伟杰
时间:
2013-6-26 12:15
同上
作者:
gzbbxu
时间:
2013-6-26 12:46
wangpan 发表于 2013-6-25 11:55
代码没上去,不好意思。
首先是什么时候用到代理?
就是在已有一个类的情况下,你需要在这个类的方法上,添 ...
很明了,谢谢
作者:
孙百鑫
时间:
2013-6-30 08:17
楼主您好,帖子长时间没有动态我已经将您的帖子改成已解决。如有问题请私密我哦~
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2