Spring AOP中JDK和CGLib动态代理商哪个更快?

作者 : 开心源码 本文共2329个字,预计阅读时间需要6分钟 发布时间: 2022-05-12 共172人阅读

一、背景

昨天一位小伙伴面试的时候被问到:Spring AOP中JDK和CGLib动态代理商哪个效率更高?整理了一下,今天特分享出来,供大家参考!

二、基本概念

首先,我们知道Spring AOP的底层实现有两种方式:一种是JDK动态代理商,另一种是CGLib的方式。

自Java 1.3以后,Java提供了动态代理商技术,允许开发者在运行期创立接口的代理商实例,后来这项技术被使用到了Spring的很多地方。

JDK动态代理商主要涉及java.lang.reflect包下边的两个类:Proxy和InvocationHandler。其中,InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调使用目标类的代码,动态地将横切逻辑和业务逻辑编织在一起。

JDK动态代理商的话,他有一个限制,就是它只能为接口创立代理商实例,而对于没有通过接口定义业务方法的类,如何创立动态代理商实例哪?答案就是CGLib。

CGLib采使用底层的字节码技术,全称是:Code Generation Library,CGLib可以为一个类创立一个子类,在子类中采使用方法阻拦的技术阻拦所有父类方法的调使用并顺势织入横切逻辑。

三、JDK 和 CGLib动态代理商区别

1、JDK动态代理商具体实现原理:

通过实现InvocationHandler接口创立自己的调使用解决器;

通过为Proxy类指定ClassLoader对象和一组interface来创立动态代理商;

通过反射机制获取动态代理商类的构造函数,其唯一参数类型就是调使用解决器接口类型;

通过构造函数创立动态代理商类实例,构造时调使用解决器对象作为参数参入;

JDK动态代理商是面向接口的代理商模式,假如被代理商目标没有接口那么Spring也无能为力,Spring通过Java的反射机制生产被代理商接口的新的匿名实现类,重写了其中AOP的加强方法。

2、CGLib动态代理商:

CGLib是一个强大、高性能的Code生产类库,可以实现运行期动态扩展java类,Spring在运行期间通过 CGlib继承要被动态代理商的类,重写父类的方法,实现AOP面向切面编程呢。

3、两者比照:

JDK动态代理商是面向接口的。

CGLib动态代理商是通过字节码底层继承要代理商类来实现(假如被代理商类被final关键字所修饰,那么抱歉会失败)。

4、用注意:

假如要被代理商的对象是个实现类,那么Spring会用JDK动态代理商来完成操作(Spirng默认采使用JDK动态代理商实现机制);

假如要被代理商的对象不是个实现类那么,Spring会强制用CGLib来实现动态代理商。

四、JDK 和 CGLib动态代理商性能比照-教科书上的形容

我们不论是看书还是看文章亦或者是我那个上搜索参考答案,可能很多时候,都可以找到如下的答复:

关于两者之间的性能的话,JDK动态代理商所创立的代理商对象,在以前的JDK版本中,性能并不是很高,尽管在高版本中JDK动态代理商对象的性能得到了很大的提升,但是他也并不是适使用于所有的场景。主要表现在如下的两个指标中:

1、CGLib所创立的动态代理商对象在实际运行时候的性能要比JDK动态代理商高不少,有研究表明,大概要高10倍;

2、但是CGLib在创立对象的时候所花费的时间却比JDK动态代理商要多很多,有研究表明,大概有8倍的差距;

3、因而,对于singleton的代理商对象或者者具备实例池的代理商,由于无需频繁的创立代理商对象,所以比较适合采使用CGLib动态代理商,反正,则比较适使用JDK动态代理商。

结果是不是如上边1、2、3条形容的那样哪?下边我们做少量小试验分析一下!

五、性能测试

1、首先有几个Java类

2、Target.java

3、TargetImpl.java

4、JdkDynamicProxyTest.java

5、CglibProxyTest.java

6、ProxyPerformanceTest.java

7、测试结果

(1)JDK 1.6

(2)JDK 1.7

(3)JDK 1.8

经过屡次实验,可以看出平均情况下的话,JDK动态代理商的运行速度已经逐步提高了,在低版本的时候,运行的性能可能不如CGLib,但是在1.8版本中运行屡次,基本都可以得到一致的测试结果,那就是JDK动态代理商已经比CGLib动态代理商快了!

但是JDK动态代理商和CGLib动态代理商的适使用场景还是不一样的哈!

六、总结

最终的测试结果大致是这样的,在1.6和1.7的时候,JDK动态代理商的速度要比CGLib动态代理商的速度要慢,但是并没有教科书上的10倍差距,在JDK1.8的时候,JDK动态代理商的速度已经比CGLib动态代理商的速度快很多了,希望小伙伴在遇到这个问题的时候能够有的放矢!

Spring AOP中的JDK和CGLib动态代理商关于这个知识点很重要,关于两者之间性能的比照经过测试试验已经有了一个初步的结果,以后再有人问你Spring AOP,不要简单的说JDK动态代理商和CGLib这两个了,是时候的可以抛出来对两者之间区别的了解,是有加分的哦!

欢迎工作一到五年的Java工程师朋友们加入Java架构开发:744677563

群内提供免费的Java架构学习资料(里面有高可使用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)正当利使用自己每一分每一秒的时间来学习提升自己,不要再使用”没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Spring AOP中JDK和CGLib动态代理商哪个更快?

发表回复