详解Java Cglib动态代理
今天来介绍另一种更为强大的代理——Cglib动态代理。
什么是Cglib动态代理?
我们先回顾一下上一篇的jdk动态代理,jdk动态代理是通过接口来在运行时动态创建委托类的代理对象,但是跟静态代理一样有一个缺点,就是必须和委托类实现相同的接口,当接口数量增加时,便需要增加代理类的数量才能满足需求,而且如果委托类是别人写的,而且没有实现任何接口,那么jdk动态代理就有些力不从心了。
这时候Cglib动态代理就脱颖而出了,Cglib并不依赖接口,可以直接生成委托类的代理对象,而且可以代理委托类的任意非final修饰的public和protected方法,我们可以先来看一个栗子。
先定义一个Programmer类:
publicclassProgrammer{ privateStringname; publicvoidsetName(Stringname){System.out.println("SettingName."); this.name=name; }publicvoidcode(){ System.out.println(name+"iswritingbugs."); } }
然后定义一个代理类:
publicclassProgrammerProxyimplementsMethodInterceptor{ /** *内部持有委托类对象的引用 */ privateObjecttarget; /** *创建代理类对象 */ publicProgrammercreateProxy(Programmerobject){ target=object; //创建Enhancer对象 Enhancerenhancer=newEnhancer(); //设置要代理的目标类,以扩展功能 enhancer.setSuperclass(this.target.getClass()); //设置单一回调对象,在回调中拦截对目标方法的调用 enhancer.setCallback(this); //设置类加载器 enhancer.setClassLoader(object.getClass().getClassLoader()); //创建代理对象 return(Programmer)enhancer.create(); } /** *回调方法:在代理实例上拦截并处理目标方法的调用,返回结果 *@paramproxy代理类 *@parammethod被代理的方法 *@paramparams该方法的参数数组 *@parammethodProxy */ @Override publicObjectintercept(Objectproxy,Methodmethod,Object[]params,MethodProxymethodProxy)throwsThrowable{ //调用之前处理 doBefore(); //调用原方法 method.invoke(target,params); //调用之后处理 doAfter(); returnnull; } privatevoiddoAfter(){ System.out.println("doafter."); } privatevoiddoBefore(){ System.out.println("dobefore."); } }
然后测试一下:
publicclassProxyTest{ @Test publicvoidtestCglibProxy(){ //创建一个Programmer对象 ProgrammerprogrammerA=newProgrammer(); programmerA.setName("Frank"); //创建代理对象 ProgrammerprogrammerProxyA=newProgrammerProxy().createProxy(programmerA); programmerProxyA.code(); //修改代理对象 programmerProxyA.setName("Wang"); programmerProxyA.code(); //修改委托类对象 programmerA.setName("Song"); programmerProxyA.code(); } }
输出如下:
SettingName.
dobefore.
Frankiswritingbugs.
doafter.
dobefore.
SettingName.
doafter.
dobefore.
Wangiswritingbugs.
doafter.
SettingName.
dobefore.
Songiswritingbugs.
doafter.
Cglib实现动态代理的步骤也不是很麻烦,先创建一个类实现MethodInterceptor接口,重写intercept方法,在intercep中可以截获委托类的所有非final修饰的public和protected方法,上例中,method.invoke(target,params);即为调用原对象的原方法,在代理类中保存了委托类对象的引用,这一点跟JDK动态代理是一样的。在调用原方法前先调用了doBefore方法,调用之后还调用了doAfter方法,从而实现了代理功能。至于createProxy方法,也只是一个固定步骤,先创建Enhance对象,然后将委托类的一些属性往里塞,然后调用create方法来动态生成代理对象。
在测试类中,为了更明显的说明代理类与委托类的关系,分别用代理类对象programmerProxyA和委托类对象programmerA对name字段进行修改,可以产生一样的效果。
下面来对比一下Cglib动态代理与JDK动态代理:
1.两者都是动态代理,都是运行时动态生成代理对象。
2.JDK动态代理利用的是接口信息来实现的代理,委托类必须实现某个或者某些接口,而Cglib则是利用继承关系,利用asm在运行时动态生成委托类的子类,从而实现对委托类的代理。因此不依赖接口。
3.Cglib由于是利用继承关系来实现代理的,因此无法代理被final修饰的类以及被final修饰的方法。
4.Cglib一般来说效率要比JDK动态代理效率更高,可以实现的代理也更为强大。
当然,具体情况具体分析,虽然Cglib比Jdk动态代理更强大,但并不一定各个地方都强行使用,有时候JDK动态代理相对来说更加简单粗暴。
至此,本篇完结,代理相关内容讲解完毕,欢迎大家继续关注。
jar包下载地址:https://www.nhooo.com/softs/570453.html
以上就是详解JavaCglib动态代理的详细内容,更多关于JavaCglib动态代理的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。