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。

相关推荐
Kingairy12 分钟前
Python面试高频题
java·python·面试
黎雁·泠崖12 分钟前
Java数组入门:定义+静态/动态初始化全解析(隐式转换+案例+避坑指南)
java·开发语言·python
不是蔬菜26 分钟前
设计模式总览
设计模式
Knight_AL40 分钟前
设计模式之责任链模式:原理解析 + Java 示例
java·设计模式·责任链模式
1candobetter42 分钟前
JAVA后端开发——深入理解 Java Static
java·开发语言
一念一花一世界1 小时前
PostIn项目实战 - 使用Mock数据尽早满足前后端接口开发需求
java·mock·postin·接口管理工具
白露与泡影1 小时前
Spring事件机制完全指南:解耦利器与实战
java·后端·spring
DYS_房东的猫1 小时前
《 C++ 零基础入门教程》第10章:C++20 核心特性 —— 编写更现代、更优雅的 C++
java·c++·c++20
好好沉淀1 小时前
Spring AI Alibaba
java·人工智能·spring
BD_Marathon1 小时前
MyBatis各种查询功能
java·开发语言·mybatis