- 时间:2022-09-02 09:02 编辑: 来源: 阅读:312
- 扫一扫,手机访问
摘要:Java-& gt;手写动态代理(实战)
《导航网站源码》
在上一篇文章中,我们针对源代码研究了动态代理的原理。事实上,在newProxyInstance之后,我们得到了一个名为$proxy0的类,它实现了我们的目标代理类的相同接口。 当我们调用我们的目标方法时,实际上是先调用这个$proxy0中的方法,然后$proxy0调用InvocationHandler中的invoke方法,invoke方法中的函数是($proxy0,目标方法,参数)。所以我们不能使用InvocationHandler中的obj作为目标方法的执行对象,而是在创建代理类的时候,给它传递一个目标代理类。因为这个obj是生成的代理类,也就是$proxy0,如果用$proxy0调用方法,会出现无限循环。 生成的$proxy0代理类通过InvocationHandler调用这里的invoke。由于这个$proxy0继承了代理类,所以请注意它是super.h.invoke,这个H就是我们在newProxyInstance中传递的媒人。我们再来看看。如何生成这个$proxy0类?我们来练习一下:既然要实现这个动态代理,那么几个类是必须的,比如我们在Proxy.newProxyInstance开头得到的$proxy0类,所以我们要自己写一个。因为我们必须在这里生成这个$proxy0类,所以图片不完整。抱歉,我们只能分开整个过程。我们有这些步骤:1 .生成我们的java代码;2.将生成的源代码保存到磁盘,保存为java文件;3.编译源代码,生成类文件;4.将类文件的内容加载到JVM中;5.在agent (1)之后返回agent对象:我们先来看看第一步是怎么做的。生成源代码:难道不有趣吗?哈哈哈,类是用字符串拼接的(我这里写死很多地方了,因为不想写得太复杂,有兴趣可以研究一下源代码怎么写)(2)在磁盘上生成源代码:这是我们生成的类(3)所以现在java文件已经生成了,下一步就是编译成类文件:java编译器:用来编译java的源程序JDK 6的特性,提供了在运行时将Java代码动态编译成字节码的功能。工具提供者:编译器https://www.aliyun.com/jiaocheng/282144.html(4)的提供者。将类文件的内容加载到JVM中:要通过classLoader做到这一点,首先要找到这个类文件,Loader.setClassFile,这个Loader就是我们在newProxyInstance中穿的classLoader。这里,我们自己也实现了一个类加载器。继承ClassLoader,需要重写它的findClass方法。首先,我们通过了这个类的路径。这里没什么好写的,因为这个地方就是找到这个类文件然后写进去。最后,字节数组被classLoader的defineClass方法转换成一个类对象(5)。被表示后的代理对象返回:获取构造函数对象并将其传入InvocationHandler,此处必须传入。因为你还记得我们用字符串写代码的时候,我们在写他的构造函数的时候,我们的InvocationHandler是它的构造函数的参数。看这段NewProxyInstance(halo class loader loader,class <?& gt[]接口,HaloinvocationHandler H),这就是为什么目标方法会被转移到invocationHandler中的invoke方法。所以在这里,真相被揭露了。最后我们来试试,看是不是这样工作的:直接运行结果:小芳我爱你~好了,这就是动态代理。感谢浏览~ ~ (* ▽ *)