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

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

一、背景

昨天一位小伙伴面试的时候被问到: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类

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

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

发表回复