浅谈CglibJdk以及ProxyFactory实现动态代理上的区别
Posted 默辨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈CglibJdk以及ProxyFactory实现动态代理上的区别相关的知识,希望对你有一定的参考价值。
动态代理就是在不改变原代码逻辑的基础上,对代码功能进行增强。
一、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源码分析可以参考:xxxx
此处仅展示部分源代码截图:
1、AOP方法的代理入口
2、找到当前Bean的所有Advice
3、找到符合当前Bean的所有的Advice
4、将所有的advisor对象添加ProxyFactory的对象中
5、获得对应的Advisor责任链并调用入口
6、最终的调用方法位置
以上是关于浅谈CglibJdk以及ProxyFactory实现动态代理上的区别的主要内容,如果未能解决你的问题,请参考以下文章
Spring读源码系列之AOP--04---proxyFactory创建代理对象
dubbo源码阅读-ProxyFactory之StubProxyFactoryWrapper本地存根
#yyds干货盘点# 老王读Spring AOP-4Spring AOP 与Spring IoC 结合的过程 && ProxyFactory 解析