日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Java學(xué)習(xí)路線:Spring框架之動(dòng)態(tài)代理

 好程序員IT 2019-07-18

Java學(xué)習(xí)路線:Spring框架之動(dòng)態(tài)代理,前言:動(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ī)工廠和代理商都具有賣(mài)東西的功能,手機(jī)代理商除了幫工廠賣(mài)手機(jī)外,還能在賣(mài)手機(jī)前打廣告推銷(xiāo),賣(mài)手機(jī)后還可以進(jìn)行售后服務(wù)。


代理模式的優(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)了相同的接口(或繼承相同的父類(lèi))

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

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

1. /**

2.  * 賣(mài)手機(jī)

3.  */

4. public interface SellMobilePhone {

5. 

6.     void sellMobilePhone();

7. }

8. /**

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

10.  */

11. public class MiPhoneFactory implements SellMobilePhone{

12. 

13.     public void sellMobilePhone() {

14.         System.out.println("生產(chǎn)了小米9手機(jī),賣(mài)出去??!");

15.     }

16. }

17. /**

18.  * 小米代理商

19.  */

20. public class MiPhoneAgent implements SellMobilePhone {

21. 

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

23.     private SellMobilePhone factory;

24. 

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

26.     public MiPhoneAgent(SellMobilePhone factory){

27.         this.factory = factory;

28.     }

29. 

30.     public void sellMobilePhone() {

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

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

33.         factory.sellMobilePhone();

34.         System.out.println("做售后,做推銷(xiāo)~~~~~~~~~~~~~~~~~");

35.     }

36. }

37. public class TestStaticProxy {

38. 

39.     @Test

40.     public void testProxy(){

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

42.         SellMobilePhone factory = new MiPhoneFactory();

43.         factory.sellMobilePhone();

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

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

46.         SellMobilePhone agent = new MiPhoneAgent(factory);

47.         //調(diào)用賣(mài)手機(jī)

48.         agent.sellMobilePhone();

49.     }

50. }

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

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

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

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

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

2) 不需要依賴(lài)某個(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)代理類(lèi)需要實(shí)現(xiàn)InvocationHandler接口

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

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

51. /**

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

53.  */

54. public class SalesAgent implements InvocationHandler{

55. 

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

57.     private Object object;

58. 

59.     /**

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

61.      * @param object 被代理者

62.      * @return 代理者

63.      */

64.     public Object createProxy(Object object){

65.         this.object = object;

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

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

68.     }

69. 

70.     /**

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

72.      */

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

74.         System.out.println("銷(xiāo)售之前,打廣告~~~~~~");

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

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

77.         System.out.println("銷(xiāo)售之后,做售后~~~~~~");

78.         return result;

79.     }

80. }

81. public class TestInvocationHandler {

82. 

83.     @Test

84.     public void testInvocation(){

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

86.         SalesAgent agent = new SalesAgent();

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

88.         SellMobilePhone sellMobilePhone = new MiPhoneFactory();

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

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

91.         phoneProxy.sellMobilePhone();

92.     }

93. }

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

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

94. /**

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

96.  *

97.  */

98. public class CGLibProxy implements MethodInterceptor {

99. 

100.     /**

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

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

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

104.      */

105.     public Object createProxy(Object object){

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

107.         Enhancer eh = new Enhancer();

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

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

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

111.         eh.setCallback(this);

112.         return eh.create();

113.     }

114. 

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

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

117.         //調(diào)用父類(lèi)對(duì)象的方法

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

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

120.         return res;

121.     }

122. }

總結(jié)

代理模式分為靜態(tài)代理和動(dòng)態(tài)代理,靜態(tài)代理只能代理某一種業(yè)務(wù),動(dòng)態(tài)代理可以代理各種業(yè)務(wù)而不用添加新的代理類(lèi),動(dòng)態(tài)代理分為JDK動(dòng)態(tài)代理和CGLib動(dòng)態(tài)代理,JDK動(dòng)態(tài)代理類(lèi)必須實(shí)現(xiàn)某個(gè)接口,如果沒(méi)有實(shí)現(xiàn)接口則可以使用CGlib實(shí)現(xiàn)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多