动态代理就是在不改变原代码逻辑的基础上,对代码功能进行增强。

文章目录

  • 一、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实现动态代理上的区别相关推荐

  1. 浅谈Android中的MVP与动态代理的结合

    浅谈Android中的MVP与动态代理的结合 本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 在Android开发平台上接触MVP足足算起来大概已经有一个年头左右.从最开始到现在经 ...

  2. jdk动态代理和cglib动态代理实现及区别

    代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能. 代理模式又分为:静态代理.jdk动态代 ...

  3. mysql declare与set的区别_浅谈MySQL存储过程中declare和set定义变量的区别

    在存储过程中常看到declare定义的变量和@set定义的变量.简单的来说,declare定义的类似是局部变量,@set定义的类似全局变量. 1.declare定义的变量类似java类中的局部变量,仅 ...

  4. 浅谈caffe中train_val.prototxt和deploy.prototxt文件的区别

    浅谈caffe中train_val.prototxt和deploy.prototxt文件的区别 标签: caffe深度学习CaffeNet 2016-11-02 16:10 1203人阅读 评论(1) ...

  5. php 如何设计索引_Mysql学习浅谈mysql的索引设计原则以及常见索引的区别

    <Mysql学习浅谈mysql的索引设计原则以及常见索引的区别>要点: 本文介绍了Mysql学习浅谈mysql的索引设计原则以及常见索引的区别,希望对您有用.如果有疑问,可以联系我们. 索 ...

  6. c语言结构共用体的作用,浅谈C语言共用体和与结构体的区别

    共用体与结构体的区别 共用体: 使用union 关键字 共用体内存长度是内部最长的数据类型的长度. 共用体的地址和内部各成员变量的地址都是同一个地址 结构体大小: 结构体内部的成员,大小等于最后一个成 ...

  7. mysql存储过程set什么意思_浅谈MySQL存储过程中declare和set定义变量的区别

    在存储过程中常看到declare定义的变量和@set定义的变量.简单的来说,declare定义的类似是局部变量,@set定义的类似全局变量. 1.declare定义的变量类似java类中的局部变量,仅 ...

  8. java动态代理上是否能再进行一层代理

    CGLIB动态代理类 import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.p ...

  9. 浅谈Java和SAP ABAP的静态代理和动态代理,以及ABAP面向切面编程的尝试

    文章目录 Java的静态代理 静态代理的优缺点 ABAP的静态代理 Spring AOP的动态代理 JDK动态代理的优缺点 CGLIB动态代理的优缺点 ABAP CGLIB的模拟实现 ABAP Pre ...

  10. java变量命名规则_浅谈JAVA开发规范与开发细节(上)

    开发团队在开发过程中,由于每个人的开发习惯,以及对于技术的理解深浅程度不一,往往一个项目在开发过程中,代码的质量,代码的风格都不尽相似,所以有一份适合团队的代码规范是非常有必要的,而一个团队的代码规范 ...

最新文章

  1. 刘铁岩:AI打通关键环节,加快物流行业数字化转型
  2. R语言绘图:28个实用程序包
  3. 第十六届智能车竞赛 | 单车拉力组浅析
  4. linux socket 时间,Socket编程获取服务器时间
  5. PHP极其强大的图片处理库Grafika详细教程(3):图像属性处理
  6. Java对异常处理或抛出之后,后面代码会不会再执行?
  7. 微型计算机硬盘为什么要分区,为什么懂电脑的人,都说硬盘不需要分区?看完你就知道了...
  8. activiti-explorer 启动报错 Error creating bean with name 'demoDataConfiguration'
  9. 转载 Div+css浏览器兼容实例分析(一)
  10. python教程视频 网盘-Python学习路线2019版(课程大纲+视频教程+网盘资源下载)...
  11. picker封装 uniapp_uni-app之picker
  12. Docker环境安装
  13. linux中了minerd之后完全清理过程
  14. JS定义const常量对象
  15. Oracle PL / SQL – INSTEAD OF触发器示例
  16. 计算机窗口的PPT,PPT幻灯片基础入门01-认识窗口界面
  17. 51单片机 数码管中断操作
  18. 绕过安卓SSL验证证书的常见四种方式
  19. 如何把软件彻底卸载的硬核方法!
  20. 小学教师听课体会 计算机,小学教师观有效课堂听课心得体会

热门文章

  1. element ui输入地内容明明符合规则还是校验报错
  2. yum 安装、 rpm安装、 源码编译安装
  3. could not connect to smtp host java_服务器发送邮件出现Could not connect to SMTP host错误 解决办法...
  4. 特征值_特征值和奇异值的关系是什么?
  5. 炖锅的蒸煮鸿蒙煮排骨煮多久能熟,蒸排骨要多长时间会熟?在家高压锅蒸排骨要多久才好...
  6. java课程设计文档_Java课程设计-文档相似性检查系统(完整)测试版
  7. injectcheck php_php简单实现sql防注入的方法
  8. 部署到gcp_Linux基础架构学习 - 使用GCP托管云解决方案 - Day09
  9. 南昌大学c语言第八章函数答案,南昌大学计算机C语言答案8
  10. 查看mysql下的内容