Spring AOP代理用的到底是CGLIB还是JDK动态代理

本文使用的AOP版本如下:


    org.springframework
    spring-aspects
    5.0.6.RELEASE

首先官方文档中有说明:

Spring AOP代理用的到底是CGLIB还是JDK动态代理_第1张图片

小结一下:

1.默认使用 JDK 动态代理,这样便可以代理所有的接口类型(interface)

2.Spring AOP也支持CGLIB的代理方式。如果我们被代理对象没有实现任何接口,则默认是CGLIB

3.我们可以强制使用CGLIB,指定proxy-target-class = "true" 或者 基于注解@EnableAspectJAutoProxy(proxyTargetClass = true)


疑问

看到这里其实已经很清楚了,但是有的同学可能会有疑问,上述第2点里,实现接口指的是什么呢?是随便写一个interface,让我们的bean实现他就可以了吗?


其实不然,Spring源码中,在选择代理的方式之前,其实对proxyTargetClass属性有这样一步处理:

org.springframework.aop.framework.ProxyProcessorSupport

Spring AOP代理用的到底是CGLIB还是JDK动态代理_第2张图片

这里对bean所实现的所有接口进行循环(前面两个判断这里不解释,有兴趣的同学点进去看下就知道了),从这里可以看出,如果bean所实现的所有接口都为空接口(没有方法),那么最后会走else分支,调用setProxyTargetClass(true),其实也就是设置了proxyTargetClass为true。

 

因此在选择代理方式的时候:

org.springframework.aop.framework.DefaultAopProxyFactory

Spring AOP代理用的到底是CGLIB还是JDK动态代理_第3张图片

config.isProxyTargetClass() 为true,会进入第一个if分支里面。在这个分支里面,如果bean它本身是一个interface或者是本身已经是一个代理对象,那么就会创建JDK代理,否则会使用CGLIB的方式创建代理对象。

 

至此,最后在总结一下:

1.默认使用 JDK 动态代理,这样便可以代理所有的接口类型(interface)

2.Spring AOP也支持CGLIB的代理方式。如果我们被代理对象没有实现任何接口或者实现的接口都是空接口,则是CGLIB

3.我们可以强制使用CGLIB,指定proxy-target-class = "true" 或者 基于注解@EnableAspectJAutoProxy(proxyTargetClass = true)

你可能感兴趣的:(Spring,AOP,动态代理)