【AOP系列】JDK动态代理源码分析(三)
这里通过JDK的源码来查看一下JDK动态代理的实现。
输出Class文件
我们尝试把JDK动态生成的$Proxy0的class给生成出来。
| 1 | public class JDKAop { | 
$Proxy0
生成的委托类的.class文件反编译后的代码
| 1 | //代理类都继承 Proxy 类 并且实现代理接口List | 
其中
| 1 | public final class $Proxy0 extends Proxy implements List | 
通过这行代码我们可以得到一下信息
- 1.既然他实现了List接口,那么我们当然可以用List来存放这个$Proxy的对象实例。 
- 2.而且前面还生成了final,所以$Proxy也自然不会有子类了。 
- 3.因为Java是单继承的,虽然不知道为啥要继承Proxy,但是这里既然继承了Proxy,那么$Proxy0就不能同时有其他的父类了。这里也可能是为啥JDK只能生成接口类型的派生类的原因,仅仅是可以能【先暂时放一下,后面自己实现一下JDK的动态代理试试,再详细分析】 
$Proxy0的详细生成过程
Proxy.newProxyInstance方法
| 1 | public static Object newProxyInstance(ClassLoader loader, | 
主要的几行代码
| 1 | //生成代理类 | 
进一步看一下getProxyClass0这个方法
| 1 | return proxyClassCache.get(loader, interfaces); | 
点击进入,其中调用了apply(key,parameter);


这里都不是关键的点,
进入ProxyClassFactory类中
| 1 | private static final class ProxyClassFactory | 
其中主要做了一下几件事情
- 1.一些规则检测,如类加载器是否有效,Class是否为接口,接口数组中的接口是否有重复等 
- 2.拼接代理需要的一些信息,如类名$Proxy+递增数字 
- 3.代理类的byte[]生成 
- 4.加载byte[]到内存,并返回Class 
接下来我们看一下byte[]是怎么生成的
ProxyGenerator.generateProxyClass();
(如果点击无法进入,需要添加JDK中的tool.jar,如图所图所示)

进入后主要的两行代码
| 1 | ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2); | 
进入generateClassFile()方法
| 1 | private byte[] generateClassFile() { | 
其中主要做了一下几件事情
- 1.Object对象中的方法特殊处理 
- 2.循环添加方法,及Method对象 
- 3.循环检测返回值类型 
- 4.静态代码块,初始化代码的生成, 
- 5.class标准文件头的拼接 
- 6.最终把所有的数据转换成byte数组返回 
有些方法细节就不再具体分析了。到此,基本上已经把JDK的源代码过了一遍了.
总结
通过阅读JDK的源代码,我们可以知道。JDK实现动态代理类的主要方法如下
- 1.组合要代理的方法,和自己要插入的代码,按照class文件的格式生成byte[], 
- 2.然后通过ClassLoader,将byte[]加载到内存,并获得Class对象。(其中的class文件的加载涉及到JVM相关知识,内容包括:装载,链接,检查,准备,解析和初始化等,感兴趣读者可自行查找相关内容。) 
- 3.最后通过反射获取到一个代理$Proxy类的构造函数,并创建一个对象返回。 
| 1 | { | 
 
		 
                      