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

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

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

2023-08-04 19:38 作者:墨雪晨澗  | 我要投稿

?

如何理解代理?

????????代理是一種軟件設(shè)計(jì)模式,它允許一個(gè)對象(稱為代理對象)控制對另一個(gè)對象(稱為真實(shí)對象)的訪問。代理對象可以通過在真實(shí)對象的前后添加額外邏輯來增強(qiáng)或限制真實(shí)對象的行為。

簡單來說代理可以幫助原對象進(jìn)行功能性增強(qiáng)(在原有的功能上添加新的功能)。

例如:明星約談先關(guān)業(yè)務(wù)后達(dá)成,收錢后,開始準(zhǔn)備唱歌,而唱歌需要前需要準(zhǔn)備場地和先關(guān)設(shè)備。此時(shí)如果該明星有以為代理(或者說經(jīng)紀(jì)人)可以幫明星進(jìn)行相關(guān)的業(yè)務(wù)洽談,收取演唱費(fèi)用,以及準(zhǔn)備相關(guān)的場地和設(shè)施,明星就只負(fù)責(zé)唱歌就可以了,對明星而言這樣效率更高業(yè)務(wù)能力更強(qiáng)了(可以理解為增強(qiáng))。

靜態(tài)代理案例:

下文關(guān)于靜態(tài)代理相關(guān)代碼的思路:

是使用靜態(tài)代理模式來實(shí)現(xiàn)對明星對象的代理。靜態(tài)代理是指在編譯時(shí)就已經(jīng)確定代理類和被代理類的關(guān)系,代理類與被代理類實(shí)現(xiàn)相同的接口或繼承相同的父類。

具體步驟如下:

  1. 首先定義一個(gè)接口或者父類,作為明星對象和代理對象的共同接口。在這個(gè)示例中,可以定義一個(gè)名為Star的接口,其中包含了明星對象和代理對象都需要實(shí)現(xiàn)的方法,比如singSongs(),talk()等。

  2. 創(chuàng)建一個(gè)真正的明星對象類Realstar,實(shí)現(xiàn)Star接口,并實(shí)現(xiàn)其中的方法。這個(gè)類是真正執(zhí)行唱歌、談話等操作的類,即被代理的對象。

  3. 創(chuàng)建一個(gè)代理對象類StarProxy,同樣實(shí)現(xiàn)Star接口,并實(shí)現(xiàn)其中的方法。這個(gè)類中含有一個(gè)成員變量,用于存儲真正的明星對象,以便在代理對象中調(diào)用。同時(shí),還可以在代理對象中實(shí)現(xiàn)一些額外的操作,比如收費(fèi)、約談項(xiàng)目等。

  4. 在代理對象的方法中,可以根據(jù)需要在執(zhí)行真正的明星對象方法之前或之后進(jìn)行一些額外的操作。例如,在singSongs()方法中,可以在調(diào)用真正的明星對象的singSongs()方法之前輸出一些準(zhǔn)備信息,在方法之后輸出一些結(jié)束信息。

  5. 在測試類中,實(shí)例化一個(gè)真正的明星對象Realstar,并設(shè)置其用戶信息。然后,實(shí)例化一個(gè)代理對象StarProxy,并設(shè)置其用戶代理信息和真正的明星對象??梢酝ㄟ^調(diào)用代理對象的方法來間接調(diào)用真正的明星對象的方法,同時(shí)享受到代理對象中實(shí)現(xiàn)的一些額外操作。

通過這樣的設(shè)計(jì),可以在不修改真正的明星對象的情況下,增加一些額外的功能和管理操作。代理對象作為真正明星對象的中介,可以處理一些與明星工作相關(guān)的事務(wù),起到解耦和管理的作用。

代碼示例:

????????為貼合實(shí)際便于理解定義一個(gè)people類


明星接口


真正明星實(shí)現(xiàn)類

明星代理實(shí)現(xiàn)類

代理或者在此處貼合情景叫經(jīng)紀(jì)人,經(jīng)紀(jì)人也實(shí)現(xiàn)明星接口,可以理解為,經(jīng)紀(jì)人是為明星做代理工作的(做一些工作管理,減輕明星負(fù)擔(dān)),所以代理(或者說經(jīng)紀(jì)人)需要知道明星有哪些技能好做的工作,所以說明星本來要做的工作,現(xiàn)在有代理去分擔(dān)一部分,唱歌的主要工作還由明星本人來,代理幫助明星做一些其他工作提高效率(可以理解為代理的作用是加強(qiáng)了明星的業(yè)務(wù)能力)。

?測試類

運(yùn)行效果:

上述代碼簡單梳理:

  1. People類是一個(gè)普通的JavaBean,用來表示一個(gè)人的信息,包括姓名和年齡。

  2. Realstar類實(shí)現(xiàn)了Star接口,它是一個(gè)真正的明星實(shí)現(xiàn)類。在這個(gè)類中,使用了@Autowired注解將People對象注入進(jìn)來,通過setter方法設(shè)置。該類實(shí)現(xiàn)了明星接口中的方法,包括singSongs()、pay()talk()。在singSongs()方法中,打印輸出明星的準(zhǔn)備信息,并返回演唱結(jié)束的提示信息;在pay()方法中,打印輸出為明星付款的金額;在talk()方法中,打印輸出約談演唱會(huì)事宜的信息。

  3. StarProxy類也實(shí)現(xiàn)了Star接口,它是一個(gè)明星代理實(shí)現(xiàn)類,相當(dāng)于經(jīng)紀(jì)人。在這個(gè)類中,同樣使用了@Autowired注解將People對象和Realstar對象注入進(jìn)來。它實(shí)現(xiàn)了明星接口中的方法,其中singSongs()方法調(diào)用了Realstar對象的singSongs()方法,實(shí)現(xiàn)了對明星唱歌的代理;pay()方法打印輸出代理收費(fèi)的金額;talk()方法打印輸出為明星代理約談項(xiàng)目的信息。

通過這樣的設(shè)計(jì),可以實(shí)現(xiàn)對真正明星對象的代理,代理對象可以在執(zhí)行真正明星對象的方法之前或之后進(jìn)行一些額外的操作,如收費(fèi)、管理和代辦事務(wù)等。同時(shí),通過依賴注入,注入了People對象,使得真正明星對象和代理對象都可以獲取到People對象的信息,以便在方法中使用。



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

動(dòng)態(tài)代理類是在運(yùn)行時(shí)動(dòng)態(tài)生成的代理類,用于代理目標(biāo)對象的方法調(diào)用。下面我將講解如何創(chuàng)建一個(gè)動(dòng)態(tài)代理類以及如何使用它。

動(dòng)態(tài)代理類的創(chuàng)建步驟如下:
????1. 創(chuàng)建一個(gè)實(shí)現(xiàn)了 `InvocationHandler` 接口的類,該類用于處理代理對象方法的調(diào)用邏輯。在該類中,需要重寫 `invoke()` 方法。
????2. 在 `invoke()` 方法中,根據(jù)需要對不同的方法進(jìn)行特定的處理。比如可以在方法調(diào)用前后進(jìn)行額外的操作,或者對方法的參數(shù)進(jìn)行校驗(yàn)等。
????3. 使用 `Proxy.newProxyInstance()` 方法創(chuàng)建代理對象。該方法需要傳入三個(gè)參數(shù):
?????????? - `ClassLoader`: 類加載器,用于加載代理類??梢允褂媚繕?biāo)對象的類加載器或者其他類加載器。
?????????? - `Interfaces`: 代理類需要實(shí)現(xiàn)的接口列表。目標(biāo)對象必須實(shí)現(xiàn)這些接口。
?????????? - `InvocationHandler`: 處理代理對象方法調(diào)用的邏輯。傳入上一步創(chuàng)建的`InvocationHandler` 實(shí)例。
????4. 將返回的代理對象強(qiáng)制轉(zhuǎn)換為目標(biāo)對象所實(shí)現(xiàn)的接口類型(如果有多個(gè)接口,則選擇其中一個(gè))。
使用動(dòng)態(tài)代理類的步驟如下:
????1. 創(chuàng)建目標(biāo)對象,即要被代理的對象。
????2. 創(chuàng)建上述提到的實(shí)現(xiàn)了 `InvocationHandler` 接口的類的實(shí)例,并在構(gòu)造方法中傳入目標(biāo)對象。
????3. 調(diào)用實(shí)現(xiàn)類的 `creatStar()` 方法獲取代理對象。這個(gè)方法內(nèi)部會(huì)根據(jù)傳入的目標(biāo)對象創(chuàng)建代理對象。
????4. 通過代理對象調(diào)用方法,實(shí)際上是調(diào)用了實(shí)現(xiàn)類中的 `invoke()` 方法。
????總結(jié)來說,動(dòng)態(tài)代理類在運(yùn)行時(shí)生成,可以處理目標(biāo)對象的方法調(diào)用,并且可以在方法調(diào)用前后執(zhí)行額外的操作。使用動(dòng)態(tài)代理類時(shí),需要自定義一個(gè) `InvocationHandler` 接口的實(shí)現(xiàn)類,并將目標(biāo)對象傳入該類中,然后通過 `Proxy.newProxyInstance()` 方法創(chuàng)建代理對象。最后,通過代理對象調(diào)用方法即可實(shí)現(xiàn)代理功能。

代理類:

測試類:


上述動(dòng)態(tài)代理類的代碼簡單梳理:

這段代碼是使用 JDK 動(dòng)態(tài)代理實(shí)現(xiàn)的代理類。下面對代碼進(jìn)行分析和講解:

  1. Starproxy02 類是代理類,它實(shí)現(xiàn)了動(dòng)態(tài)代理的邏輯。在構(gòu)造方法中接收一個(gè) Realstar 對象作為參數(shù),表示要代理的目標(biāo)對象。

  2. creatStar() 方法用于創(chuàng)建代理對象。在這個(gè)方法中,通過調(diào)用 Proxy.newProxyInstance() 方法創(chuàng)建代理對象。該方法需要傳入三個(gè)參數(shù):

    • ClassLoader: 類加載器,用來加載代理類。

    • Interfaces: 代理類需要實(shí)現(xiàn)的接口列表。

    • InvocationHandler: 處理代理對象方法調(diào)用的邏輯。

  3. InvocationHandler 是一個(gè)接口,定義了一個(gè) invoke() 方法,用于處理代理對象的方法調(diào)用。在這段代碼中,創(chuàng)建了一個(gè)匿名內(nèi)部類實(shí)現(xiàn)了 InvocationHandler 接口。在這個(gè)實(shí)現(xiàn)類中,重寫了 invoke() 方法。

  4. invoke() 方法中,首先通過判斷 method.getName().equals("singSongs") 判斷方法是否是 singSongs() 方法,如果是,則打印輸出 "動(dòng)態(tài)代理調(diào)用singSongs",然后調(diào)用真實(shí)對象的 singSongs() 方法并返回結(jié)果。

  5. 如果不是 singSongs() 方法,說明是其他方法,直接通過反射調(diào)用真實(shí)對象的相應(yīng)方法,并返回結(jié)果。

  6. AnnoTest 類的 main() 方法中,創(chuàng)建了一個(gè) Realstar 對象 realstar,并將其傳入 Starproxy02 的構(gòu)造方法中初始化代理類。然后通過調(diào)用 creatStar() 方法得到代理對象 star1。

  7. 最后,通過調(diào)用代理對象的方法,可以看到對于 singSongs() 方法,會(huì)輸出 "動(dòng)態(tài)代理調(diào)用singSongs",并且調(diào)用了真實(shí)對象的 singSongs() 方法;對于其他方法,則直接調(diào)用真實(shí)對象的相應(yīng)方法。

這段代碼通過 JDK 提供的動(dòng)態(tài)代理機(jī)制,實(shí)現(xiàn)了對 Realstar 類的代理。在代理過程中,利用了 InvocationHandler 接口的 invoke() 方法動(dòng)態(tài)處理方法調(diào)用。使用動(dòng)態(tài)代理能夠更加靈活地處理不同的目標(biāo)對象,避免了手動(dòng)編寫大量的代理類。


?運(yùn)行效果:


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

CGLIB(Code Generation Library)是一個(gè)基于字節(jié)碼生成庫的第三方庫,用于生成和修改Java類的字節(jié)碼。它可以實(shí)現(xiàn)對類的動(dòng)態(tài)代理,即創(chuàng)建目標(biāo)類的子類作為代理類。

CGLIB的動(dòng)態(tài)代理與基于接口的 JDK 動(dòng)態(tài)代理有所不同。JDK 動(dòng)態(tài)代理要求目標(biāo)對象實(shí)現(xiàn)至少一個(gè)接口,而 CGLIB 動(dòng)態(tài)代理則可以對沒有實(shí)現(xiàn)接口的類進(jìn)行代理。CGLIB 動(dòng)態(tài)代理通過生成目標(biāo)類的子類來實(shí)現(xiàn)代理,子類繼承了目標(biāo)類的行為,并且可以覆蓋或增加新的方法。

使用 CGLIB 的動(dòng)態(tài)代理,你需要引入 CGLIB 庫并使用它提供的 Enhancer 類來創(chuàng)建代理對象。以下是一個(gè)示例:



上述示例中,`CglibDynamicProxy` 實(shí)現(xiàn)了 `MethodInterceptor` 接口,并重寫了 `intercept` 方法。在 `createProxy` 方法中,創(chuàng)建了一個(gè) `Enhancer` 對象,并設(shè)置了目標(biāo)類和回調(diào)對象。在 `intercept` 方法中,可以實(shí)現(xiàn)對目標(biāo)類方法的增強(qiáng)邏輯。`proxy.invokeSuper(obj, args)` 方法通過反射調(diào)用目標(biāo)對象的方法。

使用 CGLIB 創(chuàng)建代理對象的示例代碼如下:




在上述代碼中,`RealStar` 是目標(biāo)對象,`CglibDynamicProxy` 是代理對象,通過 `proxy.createProxy(realStar)` 創(chuàng)建了代理對象,并將其轉(zhuǎn)型為 `Star` 接口類型。然后可以調(diào)用代理對象的方法,代理對象會(huì)在方法調(diào)用前后添加額外的處理邏輯。

需要注意的是,CGLIB 動(dòng)態(tài)代理的原理是生成目標(biāo)類的子類,因此目標(biāo)類不能是 `final` 類型,并且被代理的方法不能是 `final` 或 `static` 的。同時(shí),如果目標(biāo)類的方法是 `final` 類型的,那么無法對該方法進(jìn)行代理。

動(dòng)態(tài)代理和靜態(tài)代理的區(qū)別人

動(dòng)態(tài)代理和靜態(tài)代理是設(shè)計(jì)模式中的兩種代理模式,它們在實(shí)現(xiàn)上有一些區(qū)別。

?????????? 1.靜態(tài)代理: 靜態(tài)代理是在編譯時(shí)就已經(jīng)確定的代理關(guān)系,代理類和目標(biāo)類都需要實(shí)現(xiàn)同一個(gè)接口或繼承同一個(gè)父類。代理類在編譯時(shí)就已經(jīng)確定了目標(biāo)類,并且在代理類中手動(dòng)編寫了對目標(biāo)方法的調(diào)用邏輯。

示例代碼中的StarProxy類就是一個(gè)靜態(tài)代理的例子,它在編譯時(shí)就已經(jīng)確定了對Realstar類的代理關(guān)系,通過在代理類中手動(dòng)調(diào)用Realstar類的方法實(shí)現(xiàn)代理。

靜態(tài)代理的優(yōu)點(diǎn)是可以在代理類中加入額外的邏輯處理,如安全性檢查、日志記錄等。但缺點(diǎn)是代理類和目標(biāo)類耦合度高,每個(gè)目標(biāo)類都需要對應(yīng)一個(gè)代理類,如果目標(biāo)類很多,代理類的數(shù)量也會(huì)相應(yīng)增多,導(dǎo)致代碼冗余。

????????????2.動(dòng)態(tài)代理: 動(dòng)態(tài)代理是在運(yùn)行時(shí)生成代理類的代理方式,不需要手動(dòng)編寫代理類,而是利用Java提供的相關(guān)API動(dòng)態(tài)生成代理類。動(dòng)態(tài)代理可以代理任意的接口或類,無需提前確定目標(biāo)類。

動(dòng)態(tài)代理利用反射機(jī)制,在運(yùn)行時(shí)動(dòng)態(tài)生成代理類,代理類中的方法調(diào)用會(huì)通過InvocationHandler接口中的invoke()方法動(dòng)態(tài)轉(zhuǎn)發(fā)到目標(biāo)類的方法。因此,動(dòng)態(tài)代理能夠更加靈活地處理不同的目標(biāo)對象,不需要為每個(gè)目標(biāo)對象都手動(dòng)編寫一個(gè)專門的代理類。


靜態(tài)代理和動(dòng)態(tài)代理的評論 (共 條)

分享到微博請遵守國家法律
康马县| 精河县| 秀山| 象山县| 沾益县| 乐业县| 海兴县| 丹巴县| 利津县| 奈曼旗| 鹿泉市| 汽车| 石城县| 武功县| 新竹市| 潜山县| 天气| 南漳县| 北川| 南投县| 阜南县| 开封市| 渝中区| 大英县| 沧州市| 犍为县| 扶沟县| 西林县| 大同市| 石景山区| 四子王旗| 白朗县| 南川市| 墨脱县| 改则县| 鹤峰县| 乳山市| 海淀区| 开阳县| 名山县| 从化市|