基于jdk的java动态代理

基于jdk的java动态代理

问题引入

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点。
AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,提高代码的灵活性和可扩展性,AOP可以说也是这种目标的一种实现。
将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。因此AOP 将会和 OOP 整合起来,以此之长,补彼之短。

动态代理demo

首先我们有一个通用的接口DoWork以及它的一个具体实现类

在这里插入图片描述

在这里插入图片描述
如果我们希望在doWork()方法前后记录一些日子,该如何做呢?直接看jdk的动态代理实现。

在这里插入图片描述
采用代理,顾名思义需要一个代理类。jdk给我们提供了一个Proxy,通过其方法newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
InvocationHandler h) 可以得到代理对象。最终我们得到的效果如下:
在这里插入图片描述

源码调试

我们不禁要问Proxy的newProxyInstance到底做了什么?

在这里插入图片描述
通过源码我们得知,主要分2步,第一步是获取代理对象的构造函数。第二步是通过构造函数创建实例。其中重点在于第一步,我们看下它是如何获得该构造函数的。

在这里插入图片描述
这里有一个针对代理类实现接口数量的判断,但无论怎样,最终都会调用
new ProxyBuilder(ld, clv.key()).build()。从它的命名来看,我们可以猜到这是一个生成Proxy相关的代码。实际上,这里完成了2步操作。第一步
new ProxyBuilder(ld, clv.key())得到一个ProxyBuilder(这是Proxy的一个内部类),第二步通过ProxyBuilder的build()得到代理类的构造函数。所以,重点就是这个build()方法。我们看看build()是怎么做的。

在这里插入图片描述
build()里面的逻辑主要分为2步,第一步得到代理类的class对象,第二步通过class对象获取构造函数。第二步没有什么好说的。关键之处是第一步,它是如何获得这个代理对象的class呢? 秘密就在Class<?> proxyClass = defineProxyClass(module, interfaces);我们继续往下看defineProxyClass方法。
在这里插入图片描述
这个方法前面有很多判断,这不是我们关注的重点。真正的关键在于这个方法的核心功能。还是分2步走。第一步得到代理类的class文件。第二部加载这个class文件,得到class对象。关于如何动态生成class文件的细节及如何加载也不是我们关注的重点了。
至此,我们已经看完了其源码的主要逻辑。通过ProxyBuilder动态生成并加载代理对象,然后通过该代理对象的构造方法创建代理对象的实例。然而还有一个问题没有搞清楚,代理对象但实例是怎样发挥作用的呢?这个秘密就隐藏在代理对象的class文件中。我们看一下这个class的庐山真面目。

在这里插入图片描述
通过该class文件,我们可以很清楚的看到,public final class $Proxy0 extends Proxy implements DoWork,这说明代理类继承了Proxy类并实现了DoWork接口。我们重点关注doWork() 方法,看看它是如何代理的。它里面的代码逻辑是 return (String)super.h.invoke(this, m2, (Object[])null);这表明它调用了父类Proxy的成员变量InvocationHandler h 的invoke方法。再回去看我们生成代理对象调用Proxy.newProxyInstance传入的InvocationHandler入参,这里最终实现了代理了逻辑。
在这里插入图片描述
我们已经看到了如何生成代理对象,以及它的调用逻辑。相信大家对JDK的动态代理有了更深的理解。自己调试一遍吧。

Spring AOP中的应用

未完待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值