浅谈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流程解析(ProxyFactory)

Spring读源码系列之AOP--04---proxyFactory创建代理对象

dubbo源码阅读-ProxyFactory之StubProxyFactoryWrapper本地存根

#yyds干货盘点# 老王读Spring AOP-4Spring AOP 与Spring IoC 结合的过程 && ProxyFactory 解析

浅谈openresty

常量池浅谈