java动态代理,能干什么呢。假设有一种场景,我们调用某个类的所有方法,然后我们想记录下我们调用每个方法的调用时间,这个我们该怎么去实现它。比较笨的办法是我们每调用一个方法,都在方法的开始和返回之前,去计算一下时间。但是这样的话,我们写了很多重复的代码。通过动态代理,我们就能实现这样的功能,spring也是同样方式,去实现类似的功能。
首先我们定义一个接口
1 | public interface Person { |
有两个方法,现在我们想统计调用这两个方法,占用的时长统计。
1 | class Jack implements Person { |
让jack来实现这个接口,现在我们来统计jack的运行时间。
1 | final Person jack = new Jack(); |
最终得到的结果是
1 | 我是jack,我正在跑 |
通过上面简单的代码,我们已经实现了我们最初的需求,那么我们来分析,分析背后的原理。
通过查看源码可知,Proxy.newProxyInstance这个类会动态生成一个java的class类,然后动态生成的这个class类,将被实例化,供我们调用。
1 | byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0",new Class<?>[]{Person.class}); |
可通过这个代码,去保存生成的类。
1 | public final class $Proxy0 extends Proxy implements Person { |
从上面的代码可以清晰的看出来,我们调用的方法最终都被代理给了InvocationHandler,我们在InvocationHandler又反射调用被代理的对象,最终实现整个代理过程。