溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JDK和CGLib動(dòng)態(tài)代理怎么實(shí)現(xiàn)

發(fā)布時(shí)間:2021-12-22 15:50:31 來(lái)源:億速云 閱讀:129 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容介紹了“JDK和CGLib動(dòng)態(tài)代理怎么實(shí)現(xiàn)”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

前言:動(dòng)態(tài)代理是一種常用的設(shè)計(jì)模式,廣泛應(yīng)用于框架中,Spring框架的AOP特性就是應(yīng)用動(dòng)態(tài)代理實(shí)現(xiàn)的,想要理解AOP的實(shí)現(xiàn)原理我們就必須先理解動(dòng)態(tài)代理。

什么是代理模式

代理模式是GOF23設(shè)計(jì)模式之一,代理模式中存在代理者和被代理者,代理者和被代理者都具有相同的功能,并且代理者執(zhí)行功能時(shí)會(huì)附加一些額外的操作

如:手機(jī)工廠和代理商都具有賣東西的功能,手機(jī)代理商除了幫工廠賣手機(jī)外,還能在賣手機(jī)前打廣告推銷,賣手機(jī)后還可以進(jìn)行售后服務(wù)。

JDK和CGLib動(dòng)態(tài)代理怎么實(shí)現(xiàn)

代理模式的優(yōu)點(diǎn):

1)符合開(kāi)閉原則,不用修改被代理者任何的代碼,就能擴(kuò)展新的功能

2)項(xiàng)目的擴(kuò)展和維護(hù)比較方便

代理模式分為:靜態(tài)代理和動(dòng)態(tài)代理

靜態(tài)代理

什么是靜態(tài)代理

1)代理者和被代理者都實(shí)現(xiàn)了相同的接口(或繼承相同的父類)

2)代理者包含了一個(gè)被代理者的對(duì)象

3)調(diào)用功能時(shí),代理者會(huì)調(diào)用被代理者的功能,同時(shí)附加新的操作

  1. /**

  2. * 賣手機(jī)

  3. */

  4. public interface SellMobilePhone {

  5. void sellMobilePhone();

  6. }

  7. /**

  8. * 小米手機(jī)工廠

  9. */

  10. public class MiPhoneFactory implements SellMobilePhone{

  11. public void sellMobilePhone() {

  12. System.out.println("生產(chǎn)了小米9手機(jī),賣出去?。?quot;);

  13. }

  14. }

  15. /**

  16. * 小米代理商

  17. */

  18. public class MiPhoneAgent implements SellMobilePhone {

  19. //被代理者,工廠對(duì)象

  20. private SellMobilePhone factory;

  21. //通過(guò)構(gòu)造方法傳入被代理者

  22. public MiPhoneAgent(SellMobilePhone factory){

  23. this.factory = factory;

  24. }

  25. public void sellMobilePhone() {

  26. System.out.println("打廣告,做活動(dòng)~~~~~~~~~~~~~~~~~");

  27. //調(diào)用被代理者的方法

  28. factory.sellMobilePhone();

  29. System.out.println("做售后,做推銷~~~~~~~~~~~~~~~~~");

  30. }

  31. }

  32. public class TestStaticProxy {

  33. @Test

  34. public void testProxy(){

  35. //創(chuàng)建被代理者

  36. SellMobilePhone factory = new MiPhoneFactory();

  37. factory.sellMobilePhone();

  38. System.out.println("---------------------------------------");

  39. //創(chuàng)建代理者

  40. SellMobilePhone agent = new MiPhoneAgent(factory);

  41. //調(diào)用賣手機(jī)

  42. agent.sellMobilePhone();

  43. }

  44. }

靜態(tài)代理的問(wèn)題:

靜態(tài)代理只能適合一種業(yè)務(wù),如果有新的業(yè)務(wù),就必須創(chuàng)建新的接口和新的代理,如添加賣電腦的接口和電腦工廠,就要?jiǎng)?chuàng)建新的電腦代理類。

動(dòng)態(tài)代理

動(dòng)態(tài)代理的特點(diǎn):

1) 在不修改原有類的基礎(chǔ)上,為原來(lái)類添加新的功能

2) 不需要依賴某個(gè)具體業(yè)務(wù)

動(dòng)態(tài)代理分為:JDK動(dòng)態(tài)代理和CGLib動(dòng)態(tài)代理

區(qū)別是:

JDK動(dòng)態(tài)代理的被代理者必須實(shí)現(xiàn)任意接口

CGLib動(dòng)態(tài)代理不用實(shí)現(xiàn)接口,是通過(guò)繼承實(shí)現(xiàn)的

JDK動(dòng)態(tài)代理

實(shí)現(xiàn)步驟:

1)代理類需要實(shí)現(xiàn)InvocationHandler接口

2)實(shí)現(xiàn)invoke方法

3)通過(guò)Proxy類的newProxyInstance方法來(lái)創(chuàng)建代理對(duì)象

  1. /**

  2. * 動(dòng)態(tài)代理

  3. */

  4. public class SalesAgent implements InvocationHandler{

  5. //被代理者對(duì)象

  6. private Object object;

  7. /**

  8. * 創(chuàng)建代理對(duì)象

  9. * @param object 被代理者

  10. * @return 代理者

  11. */

  12. public Object createProxy(Object object){

  13. this.object = object;

  14. //Proxy.newProxyInstance創(chuàng)建動(dòng)態(tài)代理的對(duì)象,傳入被代理對(duì)象的類加載器,接口,InvocationHandler對(duì)象

  15. return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);

  16. }

  17. /**

  18. * 調(diào)用被代理者方法,同時(shí)添加新功能

  19. */

  20. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

  21. System.out.println("銷售之前,打廣告~~~~~~");

  22. //調(diào)用被代理者的方法

  23. Object result = method.invoke(object,args);

  24. System.out.println("銷售之后,做售后~~~~~~");

  25. return result;

  26. }

  27. }

  28. public class TestInvocationHandler {

  29. @Test

  30. public void testInvocation(){

  31. //創(chuàng)建動(dòng)態(tài)代理對(duì)象

  32. SalesAgent agent = new SalesAgent();

  33. //被代理對(duì)象

  34. SellMobilePhone sellMobilePhone = new MiPhoneFactory();

  35. //創(chuàng)建代理對(duì)象

  36. SellMobilePhone phoneProxy = (SellMobilePhone) agent.createProxy(sellMobilePhone);

  37. phoneProxy.sellMobilePhone();

  38. }

  39. }

CGLib動(dòng)態(tài)代理

特點(diǎn):通過(guò)繼承實(shí)現(xiàn),被代理者必須能被繼承,通過(guò)被代理類創(chuàng)建子類,子類就是父類的代理。

  1. /**

  2. * CGLib動(dòng)態(tài)代理

  3. *

  4. */

  5. public class CGLibProxy implements MethodInterceptor {

  6. /**

  7. * 返回代理對(duì)象

  8. * @param object 被代理對(duì)象

  9. * @return 代理對(duì)象

  10. */

  11. public Object createProxy(Object object){

  12. //創(chuàng)建加強(qiáng)器

  13. Enhancer eh = new Enhancer();

  14. //設(shè)置被代理對(duì)象的類為父類

  15. eh.setSuperclass(object.getClass());

  16. //設(shè)置代理對(duì)象的回調(diào)

  17. eh.setCallback(this);

  18. return eh.create();

  19. }

  20. public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

  21. System.out.println("售前~~~~~~CGLIB");

  22. //調(diào)用父類對(duì)象的方法

  23. Object res = proxy.invokeSuper(obj, args);

  24. System.out.println("售后~~~~~~CGLIB");

  25. return res;

  26. }

  27. }

“JDK和CGLib動(dòng)態(tài)代理怎么實(shí)現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI