
Spring-AOP(进阶)
什么是动态代理
动态代理其实就是
Java
中的一个方法,这个方法可以实现:动态创建一组指定的接口的实现对象(在运行时,创建实现了指定的一组接口的对象) 例如:
动态代理初体验
我们根据上面的思路来体验一下 Java 中的动态代理吧,首先我们要先写两个接口。
然后我们就先来看一下动态代理的代码:
经过测试代码运行成功,说明生成的代理对象确实实现了 A 接口和 B 接口,但是我想你一定会对代理对象如何实现了 A 接口和 B 接口感兴趣,你一定想知道如果使用代理对象调用相应接口的方法会发生什么感兴趣,下面我们一起来探究一下:
我们可以发现什么也没有发生。这是因为我们根本没有为代理对象添加实现逻辑。可是实现逻辑添加在哪里呢?哈哈,当然是
InvocationHandler
中了。下面就看一看添加了实现逻辑的代码:截图如下:
这里我们发现 A 接口和 B 接口的实现逻辑都是调用了
invoke
这个方法中的逻辑,其实除了调用代理对象的native
方法,调用代理对象的其他所有方法本质都是调用了invoke
方法,下面我们再来看第三个实例,让我们对动态代理有更深刻的认识。通过代码的结果我们大胆的猜测一下,代理对象方法的返回值其实就是
invoke
方法的返回值,代理对象其实就是使用反射机制实现的一个运行时对象。哈哈,当然这些肯定不是猜测了,其实确实就是这样。下面是时候总结一下InvocationHandler
的invoke
方法了。如下图所示:当我们调用代理对象的方法时,其对应关系就如上图所示。
初步实现 AOP
在我们对动态代理有了一定的认识之后,我们就可以实现最基本版本的 AOP 了,当然,这是一个非常残缺的 AOP 实现,甚至都不能称之为 AOP 实现。 我们先写一个接口:
然后给出该接口的实现类:
然后我们就通过动态代理来对上面的
ManWaiter
进行增强:结果如下:
你肯定要说了,这算什么 AOP,增强的代码都是硬编码到
invoke
方法中的,大家稍安勿躁,我们不是已经对需要增强的对象做了增强吗。这里可以的目标对象为manWaiter
,增强为System.out.println("你好");
和System.out.println("再见");
,切点为server()
方法调用。其实还是可以看做一下原始的 AOP 的。
完善的 AOP 实现
我们从初步实现的 AOP 中可以发现很多问题,比如我们不能把增强的逻辑硬编码到代码中,我们需要实现可变的增强,下面我们就解决一下这些问题,来实现一个比较完善的 AOP。 我们仍然引用上面的
Waiter
接口和Manwaiter
实现类。 然后我们添加一个前置增强接口:再添加一个后置增强接口:
我们把产生代理对象的代码封装为一个类:
然后我们将相关的参数注入到
ProxyFactory
后就可以通过creatProxy()
方法获取代理对象了,代码如下:结果如下:
这时候我们已经可以自定义任意的增强逻辑了,是不是很神奇。
动态代理实现 AOP 总结
通过上面的内容,我们已经通过动态代理实现了一个非常简陋的 AOP,这里的 AOP 实现还是有很多的不足之处。下面我把 Spring 中的
ProxyFactory
实现贴出来,大家可以研究一下 Spring 中的ProxyFactory
的优势在哪里,另外,Spring 中还有其他的基于动态代理实现的织入器,ProxyFactory
只是其中最基础的版本,大家有兴趣可以研究一下。
- 感谢你赐予我前进的力量