• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

详解Java Cglib动态代理

java 搞代码 4年前 (2022-01-05) 25次浏览 已收录 0个评论

这篇文章主要介绍了Java Cglib动态代理的相关资料,帮助大家更好的理解和学习Java代理,感兴趣的朋友可以了解下

  今天来介绍另一种更为强大的代理――Cglib动态代理。

  什么是Cglib动态代理?

  我们先回顾一下上一篇的jdk动态代理,jdk动态代理是通过接口来在运行时动态创建委托类的代理对象,但是跟静态代理一样有一个缺点,就是必须和委托类实现相同的接口,当接口数量增加时,便需要增加代理类的数量才能满足需求,而且如果委托类是别人写的,而且没有实现任何接口,那么jdk动态代理就有些力不从心了。

  这时候Cglib动态代理就脱颖而出了,Cglib并不依赖接口,可以直接生成委托类的代理对象,而且可以代理委托类的任意非final修饰的public和protected方法,我们可以先来看一个栗子。

  先定义一个Programmer类:

 public class Programmer { private String name; public void setName(String name) {     System.out.println("Setting Name."); this.name = name; }public void code(){ System.out.println(name + " is writing bugs."); } }

  然后定义一个代理类:

 public class ProgrammerProxy implements MethodInterceptor { /** * 内部持有委托类对象的引用 */ private Object target; /** * 创建代理类对象 */ public Programmer createProxy(Programmer object){ target = object; //创建Enhancer对象 Enhancer enhancer = new Enhancer(); //设置要代理的目标类,以扩展功能 enhancer.setSuperclass(this.target.getClass()); //设置单一回调对象,在回调中拦截对目标方法的调用 enhancer.setCallback(this); //设置类加载器 enhancer.setClassLoader(object.getClass().getClassLoader()); //创建代理对象 return (Programmer)enhancer.create(); } /** * 回调方法:在代理实例上拦截并处理目标方法的调用,返回结果 * @param proxy 代理类 * @param method 被代理的方法 * @param params 该方法的参数数组 * @param methodProxy */ @Override public Object intercept(Object proxy, Method method, Object[] params, MethodProxy methodProxy) throws Throwable { //调用之前处理 doBefore(); //调用原方法 method.invoke(target,params); //调用之后处理 doAfter(); return null; } private void doAfter() { System.out.println("do after."); } private void doBefore() { System.out.println("do before."); } }

  然后测试一下:

 public class ProxyTest { @Test public void testCglibProxy(){ //创建一个Programmer对象 Programmer programmerA = new Programmer(); programmerA.setName("Frank"); //创建代理对象 Programmer programmerProxyA = new ProgrammerProxy().createProxy(programmerA); programmerProxyA.code(); //修改代理对象 programmerProxyA.setName("Wang"); programmerProxyA.code(); //修改委托类对象 programmerA.setName("Song"); programmerProxyA.code(); } }

  输出如下:

Setting Name.
do before.
Frank is writing bugs.
do after.
do before.
Setting Name.
do af

来源gao!%daima.com搞$代*!码网

ter.
do before.
Wang is writing bugs.
do after.
Setting Name.
do before.
Song is writing bugs.
do after.

  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.gaodaima.com/softs/570453.html

以上就是详解Java Cglib动态代理的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:详解Java Cglib动态代理

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址