最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

深入解析SSH框架——代理模式

2021-03-24 16:19 作者:動力節(jié)點小王本王  | 我要投稿



代理模式

代理模式是指,為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個對象不適合或者不能直接引用另一個對象,而代理對象可以在客戶類和目標對象之間起到中介的作用。

換句話說,使用代理對象,是為了在不修改目標對象的基礎(chǔ)上,增強主業(yè)務(wù)邏輯。

客戶類真正的想要訪問的對象是目標對象,但客戶類真正可以訪問的對象是代理對象??蛻纛悓δ繕藢ο蟮脑L問是通過訪問代理對象來實現(xiàn)的。當然,代理類與目標類要實現(xiàn)同一個接口。

以生活中的“代理律師”為例來理解“代理模式”。

打官司是件非常麻煩的過程:案件調(diào)查取證、查找法律條文、起草法律文書、法庭辯論、簽署法律文件、申請法院執(zhí)行……但打官司的人只關(guān)心法宣判結(jié)果。此時,打官司的人就可聘請“代理律師”來完成整個打官司的所有事務(wù)。當事人只需與代理律師簽訂了“全權(quán)委托協(xié)議”,那么整個打官司的過程,當事人均可不出現(xiàn)。

聘請代理律師時以下幾點需要特別說明:

(1)?當事人與代理律師是在為同一件事情努力。

(2)?法院所有的具體事務(wù)都是通過代理律師完成。

(3)?在法院需要當事人完成某些工作時,代理律師會通知當事人,并為其出謀劃策,即增強當事人。

對于代理模式,需要注意以下幾點:

(1)?代理類和目標類要實現(xiàn)同一個接口,即業(yè)務(wù)接口。

(2)?客戶類對目標類的調(diào)用均是通過代理類完成的。

(3)?代理類的執(zhí)行既執(zhí)行了對目標類的增強業(yè)務(wù)邏輯,又調(diào)用了目標類的主業(yè)務(wù)邏輯。

根據(jù)代理關(guān)系建立的時間不同,可以將代理分為兩類:靜態(tài)代理與動態(tài)代理。就好比當事人與律師之間的關(guān)系一樣,也分為法律顧問與代理律師兩類。

靜態(tài)代理

?概念

靜態(tài)代理是指,代理類在程序運行前就已經(jīng)定義好,其與目標類的關(guān)系在程序運行前定義代理類 AccountProxy。這個類要實現(xiàn) IAccount?接口。并且該代理類就已經(jīng)確立。

靜態(tài)代理類似于企業(yè)與企業(yè)的法律顧問間的關(guān)系。法律顧問與企業(yè)的代理關(guān)系,并不是在“官司”發(fā)生后才建立的,而是之前就確立好的一種關(guān)系。

代理實現(xiàn)與解析

靜態(tài)代理實現(xiàn)轉(zhuǎn)賬: proxy_static

(1)定義業(yè)務(wù)接口 IAccountService,其中含有抽象方法 transfer()。

(2)定義目標類 AccountServiceImpl,該類實現(xiàn)了業(yè)務(wù)接口。在對接口方法的實現(xiàn)上,

只實現(xiàn)主業(yè)務(wù)邏輯轉(zhuǎn)賬即可。這個方法稱為目標方法。

(3)?定義代理類 AccountProxy。這個類要實現(xiàn) IAccount?接口。并且該代理類要將接口對象作為一個成員變量,還要定義一個帶參的構(gòu)造器,這個參數(shù)為接口對象。目的是,將目標對象引入代理類,以便代理類調(diào)用目標類的目標方法。

(4)?定義客戶類 Client。在客戶類中首先要創(chuàng)建目標對象,再創(chuàng)建代理對象,并使用目標對象對其進行初始化。然后由代理對象來調(diào)用執(zhí)行業(yè)務(wù)方法。

JDK?動態(tài)代理

動態(tài)代理是指,程序在整個運行過程中根本就不存在目標類的代理類,目標對象的代理對象只是由代理生成工具(如代理工廠類)在程序運行時由 JVM 根據(jù)反射等機制動態(tài)生成的。代理對象與目標對象的代理關(guān)系在程序運行時才確立。

對比靜態(tài)代理,靜態(tài)代理是指在程序運行前就已經(jīng)定義好了目標類的代理類。代理類與目標類的代理關(guān)系在程序運行之前就確立了。

概念

動態(tài)代理類似于普通當事人與聘請的律師間的關(guān)系。律師是在“官司”發(fā)生后,才由當事人聘請的。即代理關(guān)系是在“官司”發(fā)生后才確立的。

動態(tài)代理的實現(xiàn)方式常用的有兩種:使用 JDK 的 Proxy,與通過 CGLIB 生成代理。

通過 JDK 的 java.lang.reflect.Proxy 類實現(xiàn)動態(tài)代理 ,會使用其靜態(tài)方法newProxyInstance(),依據(jù)目標對象、業(yè)務(wù)接口及業(yè)務(wù)增強邏輯三者,自動生成一個動態(tài)代理對象。

public static newProxyInstance ( ClassLoader loader, Class<?>[] interfaces,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? InvocationHandler handler)

loader:目標類的類加載器,通過目標對象的反射可獲取

interfaces:目標類實現(xiàn)的接口數(shù)組,通過目標對象的反射可獲取

handler:業(yè)務(wù)增強邏輯,需要再定義。

InvocationHandler 是個接口,其具體介紹如下:

實現(xiàn)了 InvocationHandler 接口的類用于加強目標類的主業(yè)務(wù)邏輯。這個接口中有一個方法 invoke(),具體加強的代碼邏輯就是定義在該方法中的。程序調(diào)用主業(yè)務(wù)邏輯時,會自動調(diào)用 invoke()方法。

invoke()方法的介紹如下:

public Object invoke ( Object proxy, Method method, Object[] args)?

proxy:代表生成的代理對象

method:代表目標方法

args:代表目標方法的參數(shù)

由于該方法是由代理對象自動調(diào)用的,所以這三個參數(shù)的值不用程序員給出。

第二個參數(shù)為 Method 類對象,該類有一個方法也叫 invoke(),可以調(diào)用目標類的目標方法。這兩個invoke()方法,雖然同名,但無關(guān)。

public Object invoke ( Object obj, Object... args)?

obj:表示目標對象

args:表示目標方法參數(shù),就是其上一層 invoke 方法的第三個參數(shù)

該方法的作用是:調(diào)用執(zhí)行 obj 對象所屬類的方法,這個方法由其調(diào)用者 Method 對象確定。

在代碼中,一般的寫法為

method.invoke(target, args);

其中,method 為上一層 invoke 方法的第二個參數(shù)。這樣,即可調(diào)用了目標類的目標方法。

代理實現(xiàn)與解析

動態(tài)代理實現(xiàn)轉(zhuǎn)賬: proxy_dynamic

(1)?定義業(yè)務(wù)接口IAccounSevice,其中含有抽象方法 transfer()。

(2)?定義目標類 AccountServiceImpl,該類實現(xiàn)了業(yè)務(wù)接口。在對接口方法的實現(xiàn)上,只實現(xiàn)主業(yè)務(wù)邏輯。這個方法稱為目標方法。

以上兩步與靜態(tài)代理類 staticproxy 中代碼相同。

(3)?定義主業(yè)務(wù)增強邏輯類 MyExtension,該類需實現(xiàn)接口 InvocationHandler。在該類中定義一個 Object?類型的成員變量,還要定義一個帶參的構(gòu)造器,這個參數(shù)為 Object?對象。目的是,將目標對象引入該類,以便通過反射調(diào)用目標方法。

當然,也可以將這個屬性定義為 IAccount?接口類型,但最好不要這樣做,最好將其定義為 Object。因為,這樣這個主業(yè)務(wù)增強邏輯可以適用于本項目中的任何類型的目標類, 而不僅僅拘泥于某一個類。

(4)?定義客戶類 Client??蛻纛愔兄饕Z句有三句:

A、定義目標對象。在生成代理對象時會需要目標對象對其初始化。

B、定義代理對象。需要注意的是,代理類 Proxy 會通過反射機制,自動實現(xiàn) IAccount接口。代理對象需要使用目標對象對其進行初始化。

C、代理對象調(diào)用主業(yè)務(wù)方法。

CGLIB?動態(tài)代理

概念

使用 JDK 的 Proxy 實現(xiàn)代理,要求目標類與代理類實現(xiàn)相同的接口。若目標類不存在接口,則無法使用該方式實現(xiàn)。

但對于無接口的類,要為其創(chuàng)建動態(tài)代理,就要使用 CGLIB 來實現(xiàn)。CGLIB 代理的生成原理是生成目標類的子類,而子類是增強過的,這個子類對象就是代理對象。所以,使用CGLIB 生成動態(tài)代理,要求目標類必須能夠被繼承,即不能是 final 的類。

CGLIB(Code Generation Library)是一個開源項目,是一個強大的、高性能的、高質(zhì)量的代碼生成類庫。它可以在運行期擴展和增強 Java 類。Hibernate 用它來實現(xiàn)持久對象的字節(jié)碼的動態(tài)生成,Spring 用它來實現(xiàn) AOP 編程。

CGLIB 包的底層是通過使用一個小而快的字節(jié)碼處理框架 ASM(Java?字節(jié)碼操控框架),來轉(zhuǎn)換字節(jié)碼并生成新的類。CGLIB 是通過對字節(jié)碼進行增強來生成代理的。

如果說靜態(tài)代理是“法律顧問(律師)”,動態(tài)代理是“代理律師”,那么?CGLIB?代理則是“老父親的兒子”。

當事人是打官司的人,而律師也是打相同官司的人。但他們事先有個約定,就是律師只對官司相關(guān)的事情進行“增強”。這個約定是通過“接口”來實現(xiàn)的。這種是 JDK 的代理原理。

老父親是需要被增強的目標類,而兒子則是用于增強老父親的代理類。不同于當事人與律師關(guān)系的是,老父親與兒子間對于要增強的事情,事先是沒有約定的。老父親需要兒子幫助他做什么事情,即增強哪些方法,事先是沒有約定的。老父親讓其增強什么,兒子就需要增強什么。即,他們是不需要“接口”的。

代理實現(xiàn)與解析

使用?CGLIB?創(chuàng)建代理步驟: ---- cglibproxy?

Setp1:導(dǎo)入?CGLIB?的?Jar?包: cglib-full.jar。

Step2:定義目標類。注意不用實現(xiàn)任何接口。

Step3:創(chuàng)建代理類的工廠。該類要實現(xiàn) MethodInterceptor 接口。該類中完成三樣工作:

1)?聲明目標類的成員變量,并創(chuàng)建以目標類對象為參數(shù)的構(gòu)造器。用于接收目標對

象。

(2)?定義代理的生成方法,用于創(chuàng)建代理對象。方法名是任意的。代理對象即目標 類的子類。

注意,只所以在 setCallback()方法中可以寫上 this,是因為 MethodIntecepter 接口繼承自 Callback,是其子接口。查看源碼:

(3) 定義回調(diào)接口方法。對目標類的增強這在這里完成。

intercept()方法中各參數(shù)的意義:

  • proxy:代理對象

  • metho:代理對象的方法,即增強過的業(yè)務(wù)方法

  • args[]:方法參數(shù)

  • methodProxy:代理對象方法的代理對象Step4:創(chuàng)建測試類。

最后奉上視頻教程??,視頻觀看效果更佳?。∽哌^路過別忘素質(zhì)三連哦~~


深入解析SSH框架——代理模式的評論 (共 條)

分享到微博請遵守國家法律
河南省| 宣威市| 聊城市| 都昌县| 额尔古纳市| 都江堰市| 宜黄县| 珲春市| 岫岩| 会同县| 大兴区| 宁乡县| 泸州市| 班戈县| 焦作市| 沙河市| 兴宁市| 开化县| 西和县| 绥棱县| 南溪县| 略阳县| 陇西县| 兖州市| 南投市| 嘉善县| 静宁县| 台中县| 综艺| 塔城市| 新郑市| 子长县| 吉水县| 西吉县| 兴安盟| 六安市| 古田县| 泰兴市| 涞水县| 天水市| 万宁市|