JDK动态代理与Cglib动态代理(SpringBoot2.x使用spring aop示例)

我相信spring aop中使用JDK动态代理与Cglib动态代理的区别这一问题在刚毕业的同窗面试时都被问过。
咱们都会答:
JDK动态代理的目标对象须要实现接口,Cglib动态代理的目标对象不须要实现接口。
再牛逼一点的朋友可能会再答JDK动态代理经过反射来实现,Cglib动态代理经过对字节码的操做来实现的,动态代理能够用来作权限控制、事务、日志处理等做用。

再问下去咱们就开始慌了

由于咱们知道动态代理能够用来作这些功能,但刚出来咱们并无真正用过动态代理,这些框架都已经封装好了,咱们只要会增删查改就好了。

前几天个人同窗面试被问到spring aop怎么设置使用JDK仍是Cglib动态代理,他的答案是:不知道。

脑海中又出来了另外一个问题:spring aop默认使用JDK仍是Cglib动态代理?

那咱们来探讨一下。

咱们都知道JDK动态代理须要实现接口,那咱们建立一个实现接口和不实现接口的类来测试一下测试

不实现接口的类优化

实现接口的类

springboot用aspect实现aop须要的类,这里就不讲解如何使用的了代理

这个自定义注解类用于指定哪一个方法须要使用aop日志

使用springboot的test测试运行,直接运行,没有做其余的配置

打印结果,发现springboot的aop无论有没有实现接口,默认都是使用CGLIB动态代理

那么咱们如何设置aop使用的动态代理方式,咱们须要设置

spring.aop.proxy-target-class这个属性的值。

默认为true表示强制使用Cglib动态代理

如今设置成false

咱们看一下运行的结果

发现实现接口的类变成了com.sun.proxy,表示使用的是JDK的动态代理。

咱们回到以前的问题,spring aop怎么设置使用JDK仍是Cglib动态代理,答案就呼之欲出了。这里是以springboot2.0以后的版本为标准

pringboot2.0的aop,无论有没有实现接口,默认使用的都是Cglib动态代理,若是想使用JDK动态代理,须要在配置文件中设置

spring.aop.proxy-target-class=false

那么使用aop时实现了接口的类就会使用JDK动态代理,没有实现接口的类仍然使用的是Cglib动态代理。

下面简单记录一下JDK动态代理与Cglib动态代理的区别,其实不少博客都总结过,这里记录只为方便回顾

1.java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,经过修改其字节码生成子类来处理。

2.JDK动态代理只能对实现了接口的类生成代理,而不能针对类。

为何JDK动态代理必需要实现接口?

由于java的单继承,动态生成的代理类已经继承了Proxy类,就不能再继承其余的类,要与代理类联系起来,只能实现接口

CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承)

3.JDK动态代理与Cglib动态代理效率比较?

jdk1.7以前JDK动态代理的效率要低于Cglib,但jdk1.7以后,java作了优化JDK动态代理的效率要高于Cglib

虽而后来优化后JDK动态代理效率要高于Cglib,但并非反射的效率要高于操做字节码。

操做字节码要效率远高于反射

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值