在自己手動(dòng)來寫一個(gè)動(dòng)態(tài)代理前,我們先來了解一下什么靜態(tài)代理:
先定義一個(gè)Person接口和兩個(gè)實(shí)現(xiàn)類:




然后就沒了,這就是靜態(tài)代理,完全沒難度的感覺....
優(yōu)點(diǎn):可以在不對(duì)我們的XiaoFang 這個(gè)類進(jìn)行修改的前提下,對(duì)它進(jìn)行功能的拓展
缺點(diǎn):現(xiàn)在XiaoFang還只是想結(jié)婚而已,萬一它以后想買車,買房,買船,買飛機(jī)...買各種它想要的東西的時(shí)候,咋辦呢,難道每個(gè)都需要去寫嗎,因?yàn)榇韺?duì)象,需要實(shí)現(xiàn)與目標(biāo)對(duì)象同樣的接口,這樣會(huì)導(dǎo)致代理類非常多,這就很不爽了,維護(hù)起來就很蛋疼了,假如接口添加個(gè)方法,代理類跟被代理類都得去維護(hù)
動(dòng)態(tài)代理:
原理: 在底層拿到被代理對(duì)象引用,然后獲取接口,JDK從新生成一個(gè)類,同事這個(gè)類也是實(shí)現(xiàn)這個(gè)接口,把被代理對(duì)象的引用也拿到,然后編譯這個(gè)類獲取字節(jié)碼
這里我們需要改變一下代理者的內(nèi)部代碼了


首先我們來看一下這個(gè)Person 到底是個(gè)什么對(duì)象

我們先看看這個(gè)對(duì)象里頭到底是什么飛機(jī)




super.h.invoke(this, m3, (Object[])null);? 是我們getLove方法中的執(zhí)行代碼,我們可以看到m3就是這個(gè)類中的變量,在靜態(tài)代碼塊中給它賦值

我們?cè)賮砜纯催@個(gè)h 是個(gè)什么飛機(jī)

是不是突然明白了點(diǎn)什么東西,用InvocationHandler的invoke方法,我們?cè)賮砜纯催@個(gè)invoke方法

Proxy.newProxyInstance(XiaoFang.class.getClassLoader(),XiaoFang.class.getInterfaces(),matchmaker);?
當(dāng)時(shí)我們是這么做來獲取到這個(gè)$Proxy0的,現(xiàn)在我們來看看這里面是搞什么飛機(jī)






最后就為這個(gè)$proxy0 創(chuàng)建了一個(gè)對(duì)象,并且返回;
所以我們?cè)谡{(diào)用這個(gè)getlove時(shí)候流程是 先調(diào)用了$proxy的getlove方法

然后再有我們?cè)趎ewProxyInstance時(shí)傳的matchmaker 上圖就變成了:
matchmaker.invoke($proxy0,me3,null);


最后還是通過我們?cè)趧?chuàng)建代理對(duì)象時(shí)傳的被代理對(duì)象來執(zhí)行的getlove方法