在上一篇中,我們對著源碼看了一遍動態(tài)代理的原理专酗,其實我們在newProxyInstance后滥比,獲取到的是一個$proxy0這個類,這個類實現(xiàn)了我們目標(biāo)代理類相同的接口臼隔。在我們調(diào)用我們的目標(biāo)方法的時候嘹裂,其實是先調(diào)用這個$proxy0中的方法,然后$proxy0又調(diào)用了InvocationHandler中的invoke方法躬翁,而invoke方法中傳的函數(shù)就是 ($proxy0焦蘑,目標(biāo)方法,參數(shù))盒发,所以我們在InvocationHandler中不能通過參數(shù)中的obj來作為目標(biāo)方法的執(zhí)行對象例嘱,而是我們在創(chuàng)建代理類的時候狡逢,給它傳了一個目標(biāo)代理類,因為這個obj 是生成的代理類也就是$proxy0拼卵,如果用$proxy0去調(diào)用method奢浑,那么就會出現(xiàn)一個死循環(huán)。
接下里我們再來看看即寡,這個$proxy0 這個類到底該怎么生成徊哑,我們來實踐一下 :
既然要實現(xiàn)這個動態(tài)代理,那么有幾個類是必不可少的聪富,比如我們在最開始的時候?Proxy.newProxyInstance來獲取的$proxy0這個類莺丑,那么我們自己就也得來寫一個,因為我們得在這里來生成這個$proxy0 這個類
整個流程我們有這么幾個步驟 :
1.生成我們的java代碼
2.將生成的源代碼保存到磁盤,保存為java文件
3.編譯源代碼,并且生成class文件
4將class文件中的內(nèi)容奸披,加載到JVM中
5.返回被代理后的代理對象
(1):我們先來看看第一步是怎么做的昏名,生成源碼:
(2)將源碼生成在磁盤上:
(3)那么現(xiàn)在java文件已經(jīng)生成了膜钓,接下來就是把它編譯成class文件了:
JavaCompiler :jdk6的特性,用來編譯java的源程式,提供在運(yùn)行期動態(tài)編譯java代碼為字節(jié)碼的功能
ToolProvider:編譯器的提供者
(4).將class文件中的內(nèi)容嗽交,加載到JVM中:
在這里我們也自己實現(xiàn)了一個ClassLoader,繼承ClassLoader并且需要重寫它的findClass方法
(5).返回被代理后的代理對象:
最后我們來試一下,看看這樣子玩到底行不行:
直接上運(yùn)行結(jié)果:
好了跛十,這就是動態(tài)代理了彤路,謝謝大家的瀏覽喲~~~ (*^▽^*)