深入理解Spring AOP:JDK与CGLIB代理的拦截处理
版权申诉
4 浏览量
更新于2024-07-08
收藏 406KB PDF 举报
"死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理"
在Spring AOP中,代理对象的创建是为了实现面向切面编程,它允许我们在不修改原有代码的情况下,向方法添加额外的功能,如日志、事务管理等。Spring支持两种代理方式:JDK动态代理和CGLIB代理。这两种代理方式在处理拦截时有所不同。
**JDK动态代理**
JDK动态代理依赖于Java的反射机制,适用于目标类实现了接口的情况。在Spring中,`JdkDynamicAopProxy`是负责创建JDK代理对象的类。当一个Bean需要被代理时,Spring会生成一个实现了目标类所有接口的动态代理类。这个代理类会在调用目标方法时,通过实现`java.lang.reflect.InvocationHandler`接口的`invoke()`方法来处理拦截逻辑。
在`JdkDynamicAopProxy`的`getProxy()`方法中,Spring首先获取目标类实现的所有接口,并加上Spring的一些内部接口,然后通过`Proxy.newProxyInstance()`创建代理对象。代理对象在执行方法时,实际上会调用`InvocationHandler`的`invoke()`方法,这个方法会根据配置的Advisor找到对应的Advice(通知),并在调用目标方法前后执行相应的逻辑。
**CGLIB代理**
对于未实现接口的目标类,Spring会使用CGLIB库来创建代理对象。CGLIB是一个强大的高性能的代码生成库,它可以在运行期扩展Java类与实现Java接口。Spring中的`ObjenesisCglibAopProxy`负责创建CGLIB代理对象。CGLIB通过字节码技术生成一个目标类的子类,这个子类在运行时被动态加载,它重写了目标类的方法,从而能够在调用方法时插入切面逻辑。
在CGLIB代理中,拦截处理发生在`MethodInterceptor`的`intercept()`方法。Spring将所有的Advisor转换为`Callback`对象,这些`Callback`在代理对象调用方法时会被执行。每个`Callback`代表一个特定的拦截行为,例如`MethodInterceptor`。
**代理选择**
Spring会根据目标类是否实现接口来决定使用哪种代理方式。如果目标类实现了接口,那么会选择JDK动态代理;如果没有实现接口,或者为了性能考虑,可以选择CGLIB。但需要注意的是,从Spring 5开始,如果JDK版本支持,即使目标类没有接口,Spring也会优先尝试使用JDK动态代理。
**总结**
Spring AOP的两种代理方式各有优劣。JDK动态代理不需修改目标类,但要求目标类实现至少一个接口。CGLIB代理无需接口,但性能上可能略逊于JDK代理。理解这两种代理的工作原理对于深入学习Spring AOP至关重要,可以帮助我们更好地设计和优化面向切面的代码。同时,熟悉源码分析可以加深对Spring框架的理解,提升问题排查和优化的能力。
2016-07-12 上传
2022-05-31 上传
200 浏览量
1896 浏览量
2018-03-21 上传
2015-07-27 上传
2018-03-18 上传
2023-06-01 上传
一诺网络技术
- 粉丝: 0
- 资源: 2万+
最新资源
- 基于Python和Opencv的车牌识别系统实现
- 我的代码小部件库:统计、MySQL操作与树结构功能
- React初学者入门指南:快速构建并部署你的第一个应用
- Oddish:夜潜CSGO皮肤,智能爬虫技术解析
- 利用REST HaProxy实现haproxy.cfg配置的HTTP接口化
- LeetCode用例构造实践:CMake和GoogleTest的应用
- 快速搭建vulhub靶场:简化docker-compose与vulhub-master下载
- 天秤座术语表:glossariolibras项目安装与使用指南
- 从Vercel到Firebase的全栈Amazon克隆项目指南
- ANU PK大楼Studio 1的3D声效和Ambisonic技术体验
- C#实现的鼠标事件功能演示
- 掌握DP-10:LeetCode超级掉蛋与爆破气球
- C与SDL开发的游戏如何编译至WebAssembly平台
- CastorDOC开源应用程序:文档管理功能与Alfresco集成
- LeetCode用例构造与计算机科学基础:数据结构与设计模式
- 通过travis-nightly-builder实现自动化API与Rake任务构建