Spring 5.x中AOP默认依旧使用JDK动态代理
SpringBoot 2.x开始,为了解决使用JDK动态代理可能导致的类型转换异常,而使用CGLIB。
在SpringBoot 2.x中,如果需要替换使用JDK动态代理可以通过配置项spring.aop.proxy-target-class=false来进行修改,proxyTargetClass配置已无效。

在 SpringBoot 中,通过AopAutoConfiguration来自动装配 AOP。搜索这个类,查看源码:

默认情况下,是没有spring.aop.proxy-target-class这个配置项的。而此时,在 SpringBoot 2.x 中会默认使用 Cglib 来实现。如果需要修改 AOP 的实现,需要通过spring.aop.proxy-target-class这个配置项来修改。

#在application.properties文件中通过spring.aop.proxy-target-class来配置
spring.aop.proxy-target-class=false

这里提一下META-INF/spring-configuration-metadata.json文件的作用:在使用application.properties或application.yml文件时,IDEA 就是通过读取这些文件信息来提供代码提示的,SpringBoot 框架自己是不会来读取这个配置文件的。

Springboot 2.x内嵌Spring版本为Spring5.x:

但是Spring5中默认还是使用jdk,查看官网,地址为:

https://docs.spring.io/spring/docs/5.2.4.RELEASE/spring-framework-reference/core.html#spring-core:
翻译:Spring AOP 默认使用 JDK 动态代理,如果对象没有实现接口,则使用 CGLIB 代理。当然,也可以强制使用 CGLIB 代理。 

查看spring-boot-autoconfigureMETA-INF下有一个spring-configuration-metadata.json

{
      "name": "spring.aop.proxy-target-class",
      "type": "java.lang.Boolean",
      "description": "Whether subclass-based (CGLIB) proxies are to be created (true), as opposed to standard Java interface-based proxies (false).",
      "defaultValue": true
    },

改变

如果在事务中强制使用JDK动态代理,以往的知识告诉我们,我们需要将proxyTargetClass 设置成false,于是我们在springboot 中发现注解@EnableTransactionManagement 或者@EnableAspectJAutoProxy默认就为false,说明这里面的属性不起作用

///将无效
@EnableAspectJAutoProxy(proxyTargetClass = false)
@EnableTransactionManagement(proxyTargetClass = false)

同理 @EnableCaching 上的proxyTargetClass 属性也是失效的。如果偏要springboot 走JDK动态代理,那么需要在application.properties里面配置

#在application.properties文件中通过spring.aop.proxy-target-class来配置
spring.aop.proxy-target-class=false
#此时项目中走的就是JDK动态代理。

文章作者: 刘同学
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 刘同学的小站
后端 Java
喜欢就支持一下吧