什么是代理模式?代理模式有什么用?通过一个小程序分析静态代理和动态代理。自己简单实现动态代理。JDK动态代理和CGLIB动态代理的区别。
1. 代理模式有什么用
①功能增強(qiáng),在實現(xiàn)目標(biāo)功能的基礎(chǔ)上,又增加了額外功能。就像生活中的中介一樣,他跟兩邊客戶會有私下的交流。
②控制訪問,代理不讓用戶直接和目標(biāo)接觸。就像中間商一樣,他們不會讓我們接觸廠家。
?
2. 靜態(tài)代理
特點:①代理類是手動實現(xiàn)的;②代理的目標(biāo)類也是確定的。
2.1 首先定義一個Usb接口
2.2 其次創(chuàng)建兩個非public修飾的Usb接口實現(xiàn)類UsbKing和UsbSan(目標(biāo))
2.3 和Usb實現(xiàn)類進(jìn)行聯(lián)系的TaoBao和Jingdong類(代理)
2.4 測試類(用戶)
2.5 總結(jié)
①優(yōu)點:實現(xiàn)簡單、容易理解
②缺點:功能比較復(fù)雜時,代理類和目標(biāo)類數(shù)量增多;目標(biāo)類修改,會影響眾多的代理類,耦合度高,拓展性低。
?
3. 動態(tài)代理
3.1 在實現(xiàn)動態(tài)代理前,我們先回顧一下反射的內(nèi)容,通過反射直接訪問UsbKing(目標(biāo))。
3.2 使用jdk的動態(tài)代理,動態(tài)地對目標(biāo)類進(jìn)行代理,主要有三步:①通過反射得到目標(biāo)類對象;②重寫InvocationHandler的invoke方法(執(zhí)行目標(biāo)類對象的方法并進(jìn)行功能增強(qiáng));③創(chuàng)建動態(tài)代理對象并執(zhí)行相應(yīng)方法。測試類TestUsb代碼更改如下。
3.3 發(fā)生3.2的循環(huán)輸出情況,是因為handler里的invoke方法中?method.invoke(proxy, args) 執(zhí)行的是代理對象的sell方法,那么會遞歸調(diào)用handler的invoke方法,從而一直循環(huán)。為了真正執(zhí)行目標(biāo)類的方法,那么需要將目標(biāo)類對象傳給InvocationHandler,不使用匿名內(nèi)部類,創(chuàng)建一個實現(xiàn)InvocationHandler接口的MyInvocationHandler類,結(jié)構(gòu)和代碼如下。
3.4 雖然完成了動態(tài)代理,但博主這邊還要解釋一下newProxyInstance方法的三個參數(shù):目標(biāo)類對象的類加載器和接口,以及InvocationHandler對象。其中目標(biāo)類對象的類加載器作為參數(shù)可以理解,因為這可以讓目標(biāo)類對象和動態(tài)代理對象是同一個類加載器;然后InvocationHandler對象作為參數(shù)也可以理解,因為動態(tài)代理對象最終要調(diào)用handler中的invoke方法。然后目標(biāo)類對象的接口作為參數(shù)是因為動態(tài)代理對象最終要能向上轉(zhuǎn)型為接口,上述代碼的?Usb o = (Usb) Proxy.newProxyInstance() 。所以最終這個代理對象實際是實現(xiàn)了Usb接口并重寫了sell方法。可通過反射查看如下。
3.5 動態(tài)代理的優(yōu)點:①不用創(chuàng)建代理類、程序運(yùn)行時動態(tài)創(chuàng)建;②目標(biāo)類修改,不影響代理類,耦合度低,可拓展性高。
?
4. 動態(tài)代理的兩種模式——JDK動態(tài)代理和CGLIB動態(tài)代理
4.1 JDK動態(tài)代理:使用java.lang.reflect包下的InvocationHandler接口和Proxy和Method類實現(xiàn)動態(tài)代理功能。如果只是生成代理對象,可以不實現(xiàn)目標(biāo)類的接口;但若要執(zhí)行目標(biāo)類的方法,那么必須要實現(xiàn)接口。
4.2 CGLIB動態(tài)代理:第三方工具庫,通過繼承目標(biāo)類,重寫父類方法,所以類和方法不能被final修飾,實現(xiàn)功能修改。
?
?
總結(jié)
以上是生活随笔為你收集整理的什么是代理模式?代理模式有什么用?通过一个小程序分析静态代理和动态代理。自己简单实现动态代理。JDK动态代理和CGLIB动态代理的区别。的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: There is no getter f
- 下一篇: 反射中getDeclaredConstr