javaee论坛

普通会员

225648

帖子

340

回复

354

积分

楼主
发表于 2019-10-30 19:23:51 | 查看: 183 | 回复: 1

前言

本文将带着几个问题来看

到底“动态代理”动态在哪里?InvocationHandler为什么没有任何实现?对于传入的newProxyInstance()的接口类型,是否有限制?如何确认某个类是不是代理类?动态代理的实现编写你要代理的interfacepublicinterfaceAnimal{voidsay();voidjump();}某实现了Animal的类publicclassDogextendsAnimal{publicvoidsay(){System.out.println("Iamadog.");}publicvoidjump(){System.out.println("ijumpwith4legs");}}使用InvocationHandler接口

在使用动态代理时,我们需要定义一个位于代理类与委托类之间的中介类,这个中介类被要求实现InvocationHandler接口。

/***调用处理程序*/publicinterfaceInvocationHandler{Objectinvoke(Objectproxy,Methodmethod,Object[]args);}

这是固定模板的部分

中介类publicclassDynamicProxyimplementsInvocationHandler{//obj为委托类对象;privateObjectobj;publicDynamicProxy(Objectobj){this.obj=obj;}@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println("before");Objectresult=method.invoke(obj,args);System.out.println("after");returnresult;}}

中介类持有一个委托类对象引用,在invoke方法中调用了委托类对象的相应方法,看到这里是不是觉得似曾相识?

通过聚合方式持有委托类对象引用,把外部对invoke的调用最终都转为对委托类对象的调用。

动态生成代理类publicclassMain{publicstaticvoidmain(String[]args){//创建中介类实例DynamicProxyinter=newDynamicProxy(newDog());//获取代理类实例sellAnimalanimal=(Animal)(Proxy.newProxyInstance(Animal.class.getClassLoader(),newClass[]{Animal.class},inter));//通过代理类对象调用代理类方法,实际上会转到invoke方法调用animal.say();animal.jump();}}

文字描述太累赘,改用这样的图来表示。这就是动态代理了。

回到问题解答到底“动态代理”动态在哪里?

动态代理之所以被称为动态,是因为运行时才将它的类创建出来。代码开始执行时,还没有proxy类,它是根据需要从你传入的接口集创建的。

InvocationHandler为什么没有任何实现?

InvocationHandler不是proxy,它只是一个帮助类,proxy会把调用转发给他处理。

对于传入的newProxyInstance()的接口类型,是否有限制?

有限制。我们要传值给newProxyInstance()的一个接口数组,此数组内只能有接口,不能有类。要考虑访问限制,如果接口不是public,就需要在一个package,不同的接口内,不可有名称和参数完全一样的方法。

如何确认某个类是不是代理类?

通过isProxyClass可以进行判断,true则是动态代理类。

小结

动态代理模式,在不少流行的第三方框架中都有出现。

需要好好的学习一下。


普通会员

0

帖子

384

回复

389

积分
沙发
发表于 2019-11-07 10:44:35

爱你呦

您需要登录后才可以回帖 登录 | 立即注册

触屏版| 电脑版

技术支持 历史网 V2.0 © 2016-2017