在上一篇中,我们对着源码看了一遍动态代理的原理,其实我们在newProxyInstance后,获取到的是一个$proxy0这个类,这个类实现了我们目标代理类相同的接口。在我们调用我们的目标方法的时候,其实是先调用这个$proxy0中的方法,然后$proxy0又调用了InvocationHandler中的invoke方法,而invoke方法中传的函数就是 ($proxy0,目标方法,参数),所以我们在InvocationHandler中不能通过参数中的obj来作为目标方法的执行对象,而是我们在创建代理类的时候,给它传了一个目标代理类,因为这个obj 是生成的代理类也就是$proxy0,如果用$proxy0去调用method,那么就会出现一个死循环。
接下里我们再来看看,这个$proxy0 这个类到底该怎么生成,我们来实践一下 :
既然要实现这个动态代理,那么有几个类是必不可少的,比如我们在最开始的时候 Proxy.newProxyInstance来获取的$proxy0这个类,那么我们自己就也得来写一个,因为我们得在这里来生成这个$proxy0 这个类
整个流程我们有这么几个步骤 :
1.生成我们的java代码
2.将生成的源代码保存到磁盘,保存为java文件
3.编译源代码,并且生成class文件
4将class文件中的内容,加载到JVM中
5.返回被代理后的代理对象
(1):我们先来看看第一步是怎么做的,生成源码:
(2)将源码生成在磁盘上:
(3)那么现在java文件已经生成了,接下来就是把它编译成class文件了:
JavaCompiler :jdk6的特性,用来编译java的源程式,提供在运行期动态编译java代码为字节码的功能
ToolProvider:编译器的提供者
(4).将class文件中的内容,加载到JVM中:
在这里我们也自己实现了一个ClassLoader,继承ClassLoader并且需要重写它的findClass方法
(5).返回被代理后的代理对象:
最后我们来试一下,看看这样子玩到底行不行:
直接上运行结果:
好了,这就是动态代理了,谢谢大家的浏览哟~~~ (*^▽^*)