Java设计模式之代理模式(三)

spring和springboot中默认的代理方式

1、在Spring 5.x中AOP默认依旧使用JDK动态代理。

2、SpringBoot 2.x开始,为了解决使用JDK动态代理可能导致的类型转换异常,而使用CGLIB。

3、在SpringBoot 2.x中,如果需要替换使用JDK动态代理可以通过配置项spring.aop.proxy-target-class=false来进行修改,proxyTargetClass配置已无效。

在spring官网中,目前最新的6.0版本中,AOP默认依旧使用JDK动态代理。

官网地址:

https://docs.spring.io/spring-framework/docs/6.0.x/reference/html/core.html#aop-introduction-proxies

Springboot 2.x内嵌Spring版本为Spring5.x,在Spring5中默认还是使用jdk动态代理。

在 SpringBoot 1.5.x 版本中,默认还是使用 JDK 动态代理的。

搜索AopAutoConfiguration。matchIfMissing表示配置文件缺少该属性时是否可以加载,如果为true,则没有该属性也会正常加载,否则不能加载。由下图可知,在 SpringBoot 1.5.x 版本中,如果配置文件中没有配置spring.aop.proxy-target-class属性,则默认加载jdk动态代理配置类。如果配置文件中配置了spring.aop.proxy-target-class属性,且属性值为true,则加载cglib代理配置类。

在 SpringBoot 2.x 中会默认使用 cglib代理来实现,如下图所示。

如果要修改默认的代理方式,需要通过spring.aop.proxy-target-class这个配置项来修改。该配置项的意思是代理目标类,如果该配置项为false,则表示使用jdk动态代理,jdk是给接口生成代理类,如果为true,则表示使用cglib动态代理,cglib是给目标类生成代理类。

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

spring.aop.proxy-target-class=false

SpringBoot 2.x 为何默认使用 Cglib 动态代理方式

假设有一个UserService接口和UserServiceImpl实现类,此时需要在UserContoller中使用UserService。在 Spring 中通常都习惯这样写代码:

@Autowired

private UserService userService;

在这种情况下,无论是使用 JDK 动态代理,还是 CGLIB 都不会出现问题。但是,如果代码是这样的:

@Autowired

private UserServiceImpl userService;

此时如果使用 JDK 动态代理,启动时就会报错,因为 JDK 动态代理是基于接口的,代理生成的对象只能赋值给接口引用变量。而 CGLIB 就不存在这个问题,因为 CGLIB 是通过生成子类来实现的,代理对象无论是赋值给接口还是实现类,这两者都是代理对象的父类。

SpringBoot 正是出于这种考虑,于是在 2.x 版本中,将 AOP 默认实现改为了 CGLIB。

相关推荐
天天摸鱼的java工程师6 分钟前
假设你在开发订单系统时遇到高并发下库存扣减出错,如何解决?由浅入深分析
java·后端·面试
都叫我大帅哥7 分钟前
Redis的ZSet:从“青铜”到“王者”的排序神器
java·redis
一块plus10 分钟前
2025 年值得一玩的最佳 Web3 游戏
算法·设计模式·程序员
肖笙XiaoSheng18 分钟前
使用Gemini2.5 pro 优化我的定时任务(二)
java·后端·代码规范
小小霸王龙!19 分钟前
互联网大厂Java面试实录:Spring Boot与微服务在电商场景中的应用
java·spring boot·redis·微服务·电商
深栈解码22 分钟前
JUC并发编程 CAS运行机制详解
java·后端
草履虫建模23 分钟前
Postman - API 调试与开发工具 - 标准使用流程
java·测试工具·spring·json·测试用例·postman·集成学习
深栈解码23 分钟前
JUC并发编程 ThreadLocal解析
java·后端
衍生星球30 分钟前
Maven 3.9.6的下载和配置
java·maven·springboot
缘来是庄37 分钟前
设计模式之代理模式
java·设计模式·代理模式