java 动态代理 jdk为何比cglib效率低 原理总结

JDK

JDK 动态代理通过回调拦截方式,通过反射获取模板接口名字、内部方法以及参数,再原来的接口上修改,拼接,产生一个新的java代理对象(类似于mybatis的反序列化代码过程)

 

1.拼接java源代码

2.编译为class文件

3.类加载器加载新的class到内存中

4.通过反射执行方法(就是在invoke()那个方法)

 

重点:生成的代理对象不能直接调用被代理对象的方法,而是通过反射,等于说每次都得用反射调用一次,所以执行效率不高。

 

Cglib

Cglib动态代理采用继承方式,底层基于asm字节码技术参数一个新的java代理对象

1.生成class文件

2.读取class文件到内存中

3.采用fastclass索引机制执行方法(关键在于invoke()那个方法)

 

重点:Cglib代理实际上是通过继承,也就是生成一个继承被代理对象的类,编译成class文件时还会额外生成一个fastclass文件,该文件记录各个method的class索引(类名+方法名+参数),当执行某个方法时,通过计算索引,定位到具体的方法,代理对象执行该方法,然后super调用父类(执行了被代理对象的方法)。

生成代理对象时通过fastclass索引机制直接定位到被代理对象的class文件,从而实现反复调用,等于说是class复用,每次都是直接拿被代理对象的class内容执行的。

 

对比

都是需要再原来的被代理对象基础上加额外代码。前者的invoke内部通过反射,后者通过fastclass索引机制,后者实现执行效率更高(高于反射数倍)。

从最终生成的被代理对象来看:

jdk通过拼接,内部只需要一个method.invoke()就可以达到目标。

cglib则需要将被代理对象(可以是多个)的class文件通过集合形式定位好,之后先执行增强代码,之后通过回调对象来执行目标对象。

 

为何框架大多数通过接口形式?

接口形式结合多态更加方便,而且接口本身没有什么实质性代码,jdk 动态代理生成的对象,实际上执行时没有“执行被代理方法”这一步骤,而jdk生成class速度比较快(相对cglib更加轻量级),随着jdk的版本变化对反射这一块进行了优化,jdk更加快捷。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值