SpringAop使用的到底是JDK动态代理还是Cglib?

Posted 若曦`

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringAop使用的到底是JDK动态代理还是Cglib?相关的知识,希望对你有一定的参考价值。

1. 从源码分析

之前在看spring面试题的时候,不知道正确答案,网上搜了一阵子,感觉也都说得不明不白的,于是决定自己来分析一波

先给个结论:SpringAop默认使用Jdk动态代理的方式,满足某些条件可以变为Cglib

废话不多说,直接贴源码来分析

从上面源码中,其实已经可以看出来了,AOP的作者也在上面写了注释,只要满足下列三个点任意之一,那么就采用Cglib代理

① optimize标志已设置(也就是为true)

从源码可以看出optimize默认是false

这里我也不清楚在什么地方去设置其为true,应该一般情况不会更改,也就是一直为false,如果有大佬知道还请评论区指点一下。

② 设置proxyTargetClass(目标代理类)标志

更改proxyTargetClass(目标代理类)标志的方法

给Config配置类上的@EnableAspectJAutoProxy注解附值

更改之后,就会采用Cglib的方式

在注解源码里面可以看到有proxyTargetClass这个标签,且默认为false

③ 没有指定代理接口


这里的没有指定代理接口是什么意思呢,也就是在Config配置类中,没有实现SpringProxy相关的接口

如果直接继承SpringProxy相关接口,重写里面的方法,那么就会采用默认自己写的代理方法,而不会使用SpringAop提供的方法

下面两个接口都可以代替默认的jdk动态代理的方法

2. 错误的推论

至此,很明显可以得出结论,SpringAop默认是使用Jdk动态代理的方式实现Aop,如果满足上列任意一个条件,则使用Cglib的方式

那么这样的推论是否正确,实质是错误的,因为在源码中,还有一个判断的条件

也就是下列两种情况,还是会采用Jdk动态代理的方式

① 要代理的类是接口

② 要代理的类是代理类

3. 最终的推论

SpringAop默认使用JDK的方式实现Aop代理

什么时候使用Cglib代理的方式呢?

(1) 满足下列3个条件之一

① optimize标志已设置(也就是为true)
② 设置proxyTargetClass(目标代理类)标志
③ 没有指定代理接口

上述三点在标题一中有详解

(2) 同时满足下列两个条件

① 要代理的目标类不是接口
② 要代理的目标类不是代理类

自己才疏学浅,如果有错误还请大佬评论区指正

以上是关于SpringAop使用的到底是JDK动态代理还是Cglib?的主要内容,如果未能解决你的问题,请参考以下文章

SpringAop使用的到底是JDK动态代理还是Cglib?

SpringAOP:JDK动态代理

SpringAOP-JDK 动态代理和 CGLIB 代理

SpringAOP——JDK动态代理

SpringAOP——JDK动态代理

有点深度的聊聊JDK动态代理