详解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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。