spring jdk动态代理、Cglib动态代理和LoadTimeWeaver(LTW)的应用选择

本文介绍了Java中的三种织入切面方式:编译期、类加载期和运行期,并详细讨论了Spring中的JDK动态代理、CGLib动态代理以及LoadTimeWeaving(LTW)。AspectJ提供编译期和类加载期织入,而LTW需要通过JVM参数设置。在Spring项目中,单例模式推荐使用CGLib,原型模式选择JDK动态代理。当遇到JDK和CGLib局限性时,可考虑LTW。总结指出,JDK代理创建效率高但执行效率低,CGLib反之。对于aspectj LTW的效率未作探讨。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Java 语言中,从织入切面的方式上来看,存在三种织入方式:编译期织入、类加载期织入和运行期织入。编译期织入是指在Java编译期,采用特殊的编译器,将切面织入到Java类中;而类加载期织入则指通过特殊的类加载器,在类字节码加载到JVM时,织入切面;运行期织入则是采用CGLib工具或JDK动态代理进行切面的织入。 


AspectJ采用编译期织入和类加载期织入的方式织入切面,是语言级的AOP实现,提供了完备的AOP支持。它用AspectJ语言定义切面,在编译期或类加载期将切面织入到Java类中。 

 

AspectJ提供了两种切面织入方式,第一种通过特殊编译器,在编译期,将AspectJ语言编写的切面类织入到Java类中,可以通过一个Ant或Maven任务来完成这个操作;第二种方式是类加载期织入,也简称为LTW(Load Time Weaving)。 

 

如何使用Load Time Weaving?首先,需要通过JVM的-javaagent参数设置LTW的织入器类包,以代理JVM默认的类加载器;第二,LTW织入器需要一个 aop.xml文件,在该文件中指定切面类和需要进行切面织入的目标类。


在做spring项目时,如果代理对象是单例模式,选择cglib动态代理;如果是prototype模式,选择jdk动态代理。

一般不会用到Load Time Weaving代理。

但是,一些特殊情况jdk和cglib动态代理也有局限性,一些特殊情况只能选择Load Time Weaving代理。


jdk动态代理的局限:

因为jdk代理是 基于接口的动态代理技术,由于接口的方法都必然是public的,这就要求实现类的实现方法也必须是public的(不能是 protected、private等),同时不能使用static的修饰符。所以,可以实施jdk动态代理的方法只能使用public或public final修饰符的方法,其他方法不可能被动态代理,相应的也就不能实施AOP增强,换句话,即不能进行spring 增强了。


Cglib动态代理的局限:

基于Cglib字节码动态代理是通过扩展被增强类,动态创建其子类的方式进行AOP增强植入的。由于使用final、static、private修饰符的方法不能被子类覆盖,相应的,这些方法就无法实施AOP增强。


总结:jdk动态代理创建时效率比cglib高,但执行效率比cglib低。所以如果代理对象是单例模式,选择cglib动态代理;如果是prototype模式,选择jdk动态代理。

当遇到jdk和cglib代理局限性无法解决问题时,可以选择Load Time Weaving代理。


至于,aspectj 的Load Time Weaving技术的效率,没研究过,请大牛解惑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值