动态代理
代理模式包含三个角色:
- Subject主题对象:一般是一个接口,定义一些方法。
- RealSubject 具体的主题实现对象:实现Subject中定义的方法。
- Proxy 代理对象:Proxy中包含一个RealSubject的引用,由代理对象实现RealSubject方法的调用。
Subject
1 | public interface Subject { |
RealSubject
1 | public class RealSubject implements Subject { |
代理对象
1 | public class ProxyInvocationHandler implements InvocationHandler { |
测试:
1 | public class ProxyTest { |
运行结果:
1 | 开始执行方法:execute |
动态代理实现原理
在ProxyInvocationHandler中可以看到通过Proxy创建了一个代理对象,那么接下来就进入到Proxy中,看一下是如何创建代理对象的:
1 | // 创建代理对象 |
Proxy
在Proxy中newProxyInstance方法创建代理对象的时候,传入了类加载器、需要代理的Subject对象以及InvocationHandler:
- 根据类加载器和需要代理的Subject对象生成代理类的class
- 根据生成的代理类的class信息,通过构造器创建代理对象,并将InvocationHandler传入
1 | public class Proxy implements java.io.Serializable { |
生成代理类的class
getProxyClass0中首先会进行边界检查,然后根据加载器和需要代理的Subject信息从proxyClassCache缓存中获取生成的代理类的calss
,具体的实现在WeakCache的get方法中:
1 | /** |
WeakCache
WeakCache的get方法中如果根据缓存key获取对象为空,会创建一个Factory对象赋值给Supplier,Factory是WeakCache的一个内部类,它实现了Supplier接口,然后调用Supplier的get方法来生成代理类的class,接下来进入到Factory的get方法中:
1 | final class WeakCache<K, P, V> { |
Factory
Factory是WeakCache的一个内部类,它实现了Supplier接口,在get方法中,又调用了valueFactory的apply方法创建class,valueFactory是WeakCache的一个成员变量,在WeakCache的构造函数中可以看到传入了valueFactory对象进行初始化,那么接下来就需要回到Proxy类中,看一下如何实例化WeakCache的:
1 | final class WeakCache<K, P, V> { |
ProxyClassFactory
Proxy中WeakCache初始化的时候使用的是ProxyClassFactory类型的factory:
1 | public class Proxy implements java.io.Serializable { |
所以调用valueFactory的apply方法的时候会进入到ProxyClassFactory的apply方法,在apply方法中会通过ProxyGenerator动态生成代理类并加载类,然后将实例化的代理类返回:
1 | private static final class ProxyClassFactory |
ProxyGenerator
ProxyGenerator是Proxy的一个内部类,用于动态生成class:
1 | private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>> { |
代理类的生成
由于设置了sun.misc.ProxyGenerator.saveGeneratedFiles为true,所以可以在包下面看到生成的代理类$Proxy0:
- 它继承了Proxy并实现了Subject,并且在构造函数中需要传入InvocationHandler对象
- 当执行$Proxy0中的execute方法时,实际上调用的是InvocationHandler的invoke方法
1 |
|
总结
JDK的动态代理实现原理是在运行中动态生成代理类,这个代理类实现了Subject接口,在对代理类进行实例化的时候,需要传入InvocationHandler,当调用代理类的方法时,会执行InvocationHandler的invoke方法,从而完成代理功能。
参考