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?的主要内容,如果未能解决你的问题,请参考以下文章