当前位置: 代码网 > it编程>编程语言>Java > Spring AOP 支持哪两种动态代理方式(最新推荐)

Spring AOP 支持哪两种动态代理方式(最新推荐)

2025年06月27日 Java 我要评论
什么是动态代理?动态代理就是,在程序运行期,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术。在生成代理对象的过程中,目标对象不变,代理对象中的方法是目标对象方法的增强方法。可以理

什么是动态代理?

动态代理就是,在程序运行期,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术。

在生成代理对象的过程中,目标对象不变,代理对象中的方法是目标对象方法的增强方法。可以理解为运行期间,对象中方法的动态拦截,在拦截方法的前后执行功能操作。

spring aop 支持以下两种动态代理方式:

  1. jdk 动态代理 (jdk dynamic proxy)
  2. cglib 代理 (code generation library)

spring 框架会根据你的业务对象(目标对象)的情况,智能地选择其中一种来创建代理。

1. jdk 动态代理

  • 技术基础:java 官方提供的 java.lang.reflect.proxy 类和 java.lang.reflect.invocationhandler 接口,是 java 原生支持的。
  • 实现方式:在运行时,创建一个新的代理类,这个代理类会实现目标对象所实现的所有接口
  • 硬性要求被代理的目标对象必须实现至少一个接口。 如果一个类没有实现任何接口,jdk 动态代理就无法为其创建代理。
  • 工作流程:当你调用代理对象的方法时,这个调用会被转发到 invocationhandlerinvoke() 方法中。spring aop 在 invoke() 方法内部织入了你的切面逻辑(如 @before@after 等),然后再通过 java 的反射机制调用原始目标对象的方法。

2. cglib 代理

  • 技术基础:一个强大的第三方代码生成库(spring 内部集成了它),它通过字节码增强 (bytecode enhancement) 技术来工作。
  • 实现方式:在运行时,动态地创建一个被代理对象的子类作为代理对象。
  • 硬性要求:被代理的目标类不能是 final 类,需要被代理的方法也不能是 finalprivate,因为子类无法继承 final 类或重写 final/private 方法。
  • 工作流程:代理类会重写(override)父类(即你的目标对象)中所有非 final 的方法。在这些重写的方法里,spring aop 织入了切面逻辑,然后再通过调用 super.method() 来执行原始目标对象的业务逻辑。

spring 如何选择?

这是面试中的高频问题,因为这个默认行为在不同版本中有所变化。

场景spring 的选择
目标对象实现了接口老的 spring 版本传统 spring xml 配置中,默认使用 jdk 动态代理

spring boot (2.x 及以后) 中,为了统一行为和解决一些代理问题,默认依然使用 cglib
目标对象没有实现接口无论在哪个版本,都只能使用 cglib

为什么 spring boot 默认使用 cglib?
主要原因是为了解决“方法自调用时 aop 失效”的问题,并提供更一致的行为。使用 cglib 可以确保即使目标对象实现了接口,代理的也是类本身,这在处理一些复杂的依赖注入和内部调用场景时更加可靠。

当然,你也可以通过在 application.properties 中进行配置来改变这个默认行为:

# 如果设置为 true (默认值),则统一使用 cglib
# 如果设置为 false,则在目标对象实现接口时,会优先使用 jdk 动态代理
spring.aop.proxy-target-class=true 

总结对比

特性jdk 动态代理cglib 代理
代理方式基于接口 (实现共同接口)基于继承 (创建子类)
前提条件目标对象必须实现接口目标对象不能是 final 类
性能在早期版本中,通过反射调用性能略低于 cglib。但在目前jdk 版本中,两者性能差距已经非常小。性能通常被认为略高,因为它直接操作字节码并调用 super
spring boot 默认

到此这篇关于spring aop 支持哪两种动态代理方式?的文章就介绍到这了,更多相关spring aop动态代理内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com