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

  • Post author:
  • Post category:其他


本文使用的AOP版本如下:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.0.6.RELEASE</version>
</dependency>

首先官方文档中有说明:

小结一下:

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

这里

对bean所实现的所有接口进行循环

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

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

org.springframework.aop.framework.DefaultAopProxyFactory

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)



版权声明:本文为w449226544原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。