一、动态代理
动态代理指的是在运行的时候动态生成代理类。生成动态代理的方式有很多,比如Java动态代理,Spring中的cglib库等等。
二、动态代理例子
假如我们有一个接口类Car,代码实现如下:
1 | /** |
同时我们有一个Minicooper类实现了Car接口,代码如下:
1 | /** |
在Java动态代理中,生成代理需要实现InvocationHandler,代码如下:
1 | /** |
执行main方法,可以看到输出结果如下图:
- Car:首先定义了一个接口以及接口实现类
- Proxy:通过Proxy可以生成一个代理对象。在获取代理对象的Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)方法中,loader指的是需要被代理的类的ClassLoader,interfaces是需要被代理的类的接口,而h是InvocationHandler,动态代理对象调用方法的时候,要发送到哪个InvocationHandler上。
- InvocationHandler:InvocationHandler只有一个接口,就是Object invoke(Object proxy, Method method, Object[] args)方法,是代理类方法的真正执行的地方。proxy是调用的真实对象。method,我们调用的真实对象的方法。args,要调用真实对象的方法时接受的参数。
三、动态代理优缺点
从上面可以看到,如果我们需要在方法执行的前后增加自定义的逻辑,做一些特殊的处理,比如记录日志等等都可以使用动态代理的方式。但是动态代理只支持接口层面,而无法做到类层面的动态代理。
四、动态代理处理流程
接下来通过debug代码的方式,首先看一下代理类怎么生成,从我们的函数调用入口跟进去:
跟进来可以看到具体的实现如下图:
可以看到实际上是通过反射的方式生成了一个实例,而这个实例的参数就是之前定义的InvocationHandler。
而在执行方法的时候,实际上执行的就是就是我们的InvocationHandler的invoke方法: