浅谈Cglib、Jdk以及ProxyFactory实现动态代理上的区别
动态代理就是在不改变原代码逻辑的基础上,对代码功能进行增强。
文章目录
- 一、Jdk动态代理
- 二、Cglib动态代理
- 三、ProxyFactory动态代理
- 四、Spring中AOP源代码分享
一、Jdk动态代理
Jdk的动态代理是基于接口的,即如果想要对目标对象进行增强,目标对象一定要实现某一个接口,因为传入的参数就是接口。
在Spring与MyBatis的整合过程中,就是使用jdk的动态代理,对Mapper文件进行代理,最终成为Spring中的Bean对象。
1、新增一个UserService接口
2、新增一个接口的实现类UserrServiceImpl
3、编写Jdk动态代理测试类
测试结果:
二、Cglib动态代理
Cglib接触比较少,但他也是一种实现动态代理的方式,使用该方式进行功能增强的时候,被代理的对象不需要实现接口,可以简单的理解为要求更低。
1、对之前的UserServiceImpl类进行改造
2、编写对应的Cglib测试代码
测试结果:
补充:
3、对同一个类的不同方法使用不同的代理方法
对该cglib代理测试方法进行改造。使得我们在调用show方法时,触发对应的增强功能;使用test方法的时候,不进行任何的增强操作。
setCallbacks方法内编写方法的代理逻辑
setCallbackFilter方法内编写被代理对象的方法过滤逻辑
测试结果:
三、ProxyFactory动态代理
前面介绍了两种不同的实现动态代理的方式。在Spring的动态代理中,同样支持上面的两种不同形式的动态代理,Spring会根据代理对象的不同条件,选择使用不同的实现动态代理的方式。
试问,如果让你实现一个功能,如何让两个不同的操作,变得统一?
你可以试着想一想Spring是如何使用xml形式、@Bean形式、@Component形式定义Bean的。没错,就是定义一个中间态,即BeanDefinition。
Spring这里也有同样的设计,它将两个不同的对象操作集中到一个ProxyFactory对象上,最终使用ProxyFactory对象来执行对应的动态代理操作。
Spring中的AOP就是使用ProxyFactory来实现的,所以下面的测试代码,我也仿造AOP部分的代码进行测试
1、编写对应的Before方法
2、编写对应的After方法
3、编写对应的Throws方法
4、编写对应的测试方法
如果在advice中不添加MethodInterceptor对象,那么就会使用默认的逻辑,即仅完成show方法的调用。
即此处展示的代码MethodInterceptor部分的代码可以省略,然后将代理逻辑都封装到advice实现类中即可。
观察测试代码,我们可以发现,使用factory.getProxy()获取的结果再强转为UserService后是一个null,一个null依然能够调用show方法,由此可见此时是使用代理对象进行方法调用的,通过旁边的调试框我们也不难发现使用的是Cglib代理方法生成了代理对象。
即如果我们想要执行方法后的对象,只需要在return的时候,返回我们的proceed对象就好了。
5、高级版本,更细粒度的代理
通过观察addAdvice方法的底层我们可以发现,我们添加的addvice对象,最终都会封装为advisor对象
测试代码:
Advice + Pointcut = Advisor
Pointcut:何种条件才能满足切入点条件,即何种条件才进行Advice的代理逻辑
Advice:对应的代理逻辑
理解使用该种方式定义Advisor,对于Spring中AOP源码部分理解起着至关重要的作用!!!
测试结果:
MoBeforeAdvice是默认添加的代理逻辑,所以两个方法都会进行调用
MoAfterAdvice只有当调用的方法为test的时候才进行调用
四、Spring中AOP源代码分享
Spring的AOP就是通过ProxyFactory进行实现的,通过观察上面的内容我们不难发现,想要完成对一个方法的代理,大致需要以下一个步骤即可:
1. 找到符合当前Bean的所有的Advice
2. 将所有的Advice添加到ProxyFactory的对象中
3. 调用对应的方法
其实AOP就这么简单,详细的AOP源码分析可以参考:浅谈SpringAOP功能源码执行逻辑
此处仅展示部分源代码截图:
1、AOP方法的代理入口
2、找到当前Bean的所有Advice
3、找到符合当前Bean的所有的Advice
4、将所有的advisor对象添加ProxyFactory的对象中
5、获得对应的Advisor责任链并调用入口
6、最终的调用方法位置
浅谈Cglib、Jdk以及ProxyFactory实现动态代理上的区别相关推荐
- 浅谈Android中的MVP与动态代理的结合
浅谈Android中的MVP与动态代理的结合 本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 在Android开发平台上接触MVP足足算起来大概已经有一个年头左右.从最开始到现在经 ...
- jdk动态代理和cglib动态代理实现及区别
代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能. 代理模式又分为:静态代理.jdk动态代 ...
- mysql declare与set的区别_浅谈MySQL存储过程中declare和set定义变量的区别
在存储过程中常看到declare定义的变量和@set定义的变量.简单的来说,declare定义的类似是局部变量,@set定义的类似全局变量. 1.declare定义的变量类似java类中的局部变量,仅 ...
- 浅谈caffe中train_val.prototxt和deploy.prototxt文件的区别
浅谈caffe中train_val.prototxt和deploy.prototxt文件的区别 标签: caffe深度学习CaffeNet 2016-11-02 16:10 1203人阅读 评论(1) ...
- php 如何设计索引_Mysql学习浅谈mysql的索引设计原则以及常见索引的区别
<Mysql学习浅谈mysql的索引设计原则以及常见索引的区别>要点: 本文介绍了Mysql学习浅谈mysql的索引设计原则以及常见索引的区别,希望对您有用.如果有疑问,可以联系我们. 索 ...
- c语言结构共用体的作用,浅谈C语言共用体和与结构体的区别
共用体与结构体的区别 共用体: 使用union 关键字 共用体内存长度是内部最长的数据类型的长度. 共用体的地址和内部各成员变量的地址都是同一个地址 结构体大小: 结构体内部的成员,大小等于最后一个成 ...
- mysql存储过程set什么意思_浅谈MySQL存储过程中declare和set定义变量的区别
在存储过程中常看到declare定义的变量和@set定义的变量.简单的来说,declare定义的类似是局部变量,@set定义的类似全局变量. 1.declare定义的变量类似java类中的局部变量,仅 ...
- java动态代理上是否能再进行一层代理
CGLIB动态代理类 import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.p ...
- 浅谈Java和SAP ABAP的静态代理和动态代理,以及ABAP面向切面编程的尝试
文章目录 Java的静态代理 静态代理的优缺点 ABAP的静态代理 Spring AOP的动态代理 JDK动态代理的优缺点 CGLIB动态代理的优缺点 ABAP CGLIB的模拟实现 ABAP Pre ...
- java变量命名规则_浅谈JAVA开发规范与开发细节(上)
开发团队在开发过程中,由于每个人的开发习惯,以及对于技术的理解深浅程度不一,往往一个项目在开发过程中,代码的质量,代码的风格都不尽相似,所以有一份适合团队的代码规范是非常有必要的,而一个团队的代码规范 ...
最新文章
- 刘铁岩:AI打通关键环节,加快物流行业数字化转型
- R语言绘图:28个实用程序包
- 第十六届智能车竞赛 | 单车拉力组浅析
- linux socket 时间,Socket编程获取服务器时间
- PHP极其强大的图片处理库Grafika详细教程(3):图像属性处理
- Java对异常处理或抛出之后,后面代码会不会再执行?
- 微型计算机硬盘为什么要分区,为什么懂电脑的人,都说硬盘不需要分区?看完你就知道了...
- activiti-explorer 启动报错 Error creating bean with name 'demoDataConfiguration'
- 转载 Div+css浏览器兼容实例分析(一)
- python教程视频 网盘-Python学习路线2019版(课程大纲+视频教程+网盘资源下载)...
- picker封装 uniapp_uni-app之picker
- Docker环境安装
- linux中了minerd之后完全清理过程
- JS定义const常量对象
- Oracle PL / SQL – INSTEAD OF触发器示例
- 计算机窗口的PPT,PPT幻灯片基础入门01-认识窗口界面
- 51单片机 数码管中断操作
- 绕过安卓SSL验证证书的常见四种方式
- 如何把软件彻底卸载的硬核方法!
- 小学教师听课体会 计算机,小学教师观有效课堂听课心得体会
热门文章
- element ui输入地内容明明符合规则还是校验报错
- yum 安装、 rpm安装、 源码编译安装
- could not connect to smtp host java_服务器发送邮件出现Could not connect to SMTP host错误 解决办法...
- 特征值_特征值和奇异值的关系是什么?
- 炖锅的蒸煮鸿蒙煮排骨煮多久能熟,蒸排骨要多长时间会熟?在家高压锅蒸排骨要多久才好...
- java课程设计文档_Java课程设计-文档相似性检查系统(完整)测试版
- injectcheck php_php简单实现sql防注入的方法
- 部署到gcp_Linux基础架构学习 - 使用GCP托管云解决方案 - Day09
- 南昌大学c语言第八章函数答案,南昌大学计算机C语言答案8
- 查看mysql下的内容