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。

相关推荐
long3167 小时前
Java 新手入门与实战开发指南
java·开发语言
执笔画流年呀7 小时前
Linux搭建Java项目部署环境
java·linux·运维
程序员天天困7 小时前
Arthas ognl 表达式从入门到实战:掌握在线调试最强的表达式引擎
java·jvm·后端
IT_Octopus8 小时前
Spring Boot 中 ThreadLocal 请求上下文的完整生命周期
java·spring boot·spring
用户40966601317518 小时前
Lombok 你用对了吗?@Data 之外的 6 个隐藏神器
java·后端·代码规范
梅头脑8 小时前
交易跨10个库、日均千万订单——选错一次分布式事务方案,加班三个月重写
java·分布式
久久学姐9 小时前
基础转码学 AI:Java+Python 双语言入门,3 个月可落地实战项目
java·python·ai·转码·实战项目
花生了什么事o9 小时前
synchronized 与 ReentrantLock:Java 锁机制原理与实现对比
java·开发语言
长不胖的路人甲10 小时前
Serial 串行、Parallel 并行、CMS 并发收集器
java·开发语言·jvm
IT_Octopus10 小时前
Spring Boot 线程池关闭:destroyMethod 的作用与最佳实践
java·spring boot·后端