最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java代理模式(Proxy)實(shí)現(xiàn)方法詳解

 更新時(shí)間:2025年04月21日 09:30:46   作者:冰糖心書(shū)房  
這篇文章主要介紹了Java代理模式(Proxy)實(shí)現(xiàn)的相關(guān)資料,代理模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,通過(guò)引入代理對(duì)象來(lái)控制對(duì)目標(biāo)對(duì)象的訪問(wèn),代理模式的優(yōu)點(diǎn)包括職責(zé)清晰、擴(kuò)展性好、保護(hù)目標(biāo)對(duì)象和增強(qiáng)功能,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、什么是代理模式?

  • 定義: 代理模式是一種結(jié)構(gòu)型設(shè)計(jì)模式。 它為另一個(gè)對(duì)象(目標(biāo)對(duì)象/被代理對(duì)象)提供一個(gè)代理(或占位符),以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。
  • 核心思想: 通過(guò)引入一個(gè)代理對(duì)象,客戶端不直接訪問(wèn)目標(biāo)對(duì)象,而是通過(guò)代理對(duì)象來(lái)間接訪問(wèn)目標(biāo)對(duì)象。 代理對(duì)象可以控制對(duì)目標(biāo)對(duì)象的訪問(wèn),并可以在訪問(wèn)前后添加額外的操作。
  • 意圖: 控制對(duì)一個(gè)對(duì)象的訪問(wèn),可以延遲加載、訪問(wèn)控制、增強(qiáng)功能等。

二、代理模式的結(jié)構(gòu)

代理模式通常包含以下幾個(gè)角色:

  • Subject (抽象主題):

    • 定義了 RealSubject 和 Proxy 的共同接口。 客戶端通過(guò) Subject 接口訪問(wèn)目標(biāo)對(duì)象。
    • 通常是一個(gè)接口或抽象類。
  • RealSubject (真實(shí)主題/目標(biāo)對(duì)象/被代理對(duì)象):

    • 定義了真正的業(yè)務(wù)邏輯。
    • 實(shí)現(xiàn)了 Subject 接口。
  • Proxy (代理):

    • 持有 RealSubject 對(duì)象的引用。
    • 實(shí)現(xiàn)了 Subject 接口,與 RealSubject 具有相同的方法。
    • 控制對(duì) RealSubject 對(duì)象的訪問(wèn),并可以在訪問(wèn)前后添加額外的操作。
    • 客戶端通過(guò) Proxy 對(duì)象間接訪問(wèn) RealSubject 對(duì)象。

UML 類圖:

+----------------+       +----------------+       +----------------+
|   <<Subject>>   |       |     Proxy      |       |  RealSubject   |
+----------------+       +----------------+       +----------------+
| +request()     |------>| -realSubject   |------>| +request()     |
+----------------+       | +request()     |       +----------------+
                             +preRequest()
                             +postRequest()

三、代理模式的類型

根據(jù)代理的創(chuàng)建時(shí)間和功能,可以將代理模式分為以下幾種類型:

  • 靜態(tài)代理 (Static Proxy):

    • 特點(diǎn): 在編譯時(shí)就已經(jīng)確定了代理類和被代理類之間的關(guān)系。 代理類和被代理類都需要實(shí)現(xiàn)相同的接口。
    • 優(yōu)點(diǎn): 實(shí)現(xiàn)簡(jiǎn)單,易于理解。
    • 缺點(diǎn):
      • 代碼冗余: 如果需要代理多個(gè)類,就需要?jiǎng)?chuàng)建多個(gè)代理類,導(dǎo)致代碼冗余。
      • 可維護(hù)性差: 如果接口發(fā)生變化,代理類和被代理類都需要進(jìn)行修改。
  • 動(dòng)態(tài)代理 (Dynamic Proxy):

    • 特點(diǎn): 在運(yùn)行時(shí)動(dòng)態(tài)地生成代理類,無(wú)需手動(dòng)創(chuàng)建代理類。
    • 優(yōu)點(diǎn):
      • 靈活性高: 可以代理任何實(shí)現(xiàn)了接口的類,無(wú)需修改原始代碼。
      • 代碼復(fù)用: 可以使用同一個(gè)代理類來(lái)代理多個(gè)不同的類。
      • 可維護(hù)性好: 如果接口發(fā)生變化,只需要修改代理邏輯,無(wú)需修改被代理類。
    • 缺點(diǎn):
      • 實(shí)現(xiàn)復(fù)雜: 動(dòng)態(tài)代理的實(shí)現(xiàn)比靜態(tài)代理復(fù)雜。
      • 性能開(kāi)銷: 動(dòng)態(tài)代理需要使用反射機(jī)制,性能比靜態(tài)代理略低。
    • Java 中的動(dòng)態(tài)代理:
      • JDK 動(dòng)態(tài)代理: Java 提供的內(nèi)置動(dòng)態(tài)代理機(jī)制,只能代理實(shí)現(xiàn)了接口的類。
      • CGLIB 動(dòng)態(tài)代理: 第三方庫(kù)提供的動(dòng)態(tài)代理機(jī)制,可以代理沒(méi)有實(shí)現(xiàn)接口的類。
  • 其他代理

    • 保護(hù)代理 用于控制對(duì)敏感對(duì)象的訪問(wèn)。
    • 遠(yuǎn)程代理 用于訪問(wèn)遠(yuǎn)程對(duì)象。
    • 虛擬代理 通過(guò)代理延遲創(chuàng)建開(kāi)銷大的對(duì)象

四、代理模式的實(shí)現(xiàn)方式 (Java)

  • 靜態(tài)代理:

    // 抽象主題
    interface Image {
        void display();
    }
    
    // 真實(shí)主題
    class RealImage implements Image {
        private String filename;
    
        public RealImage(String filename) {
            this.filename = filename;
            loadImageFromDisk();
        }
    
        private void loadImageFromDisk() {
            System.out.println("Loading image: " + filename);
        }
    
        @Override
        public void display() {
            System.out.println("Displaying image: " + filename);
        }
    }
    
    // 代理
    class ImageProxy implements Image {
        private RealImage realImage;
        private String filename;
    
        public ImageProxy(String filename) {
            this.filename = filename;
        }
    
        @Override
        public void display() {
            if (realImage == null) {
                realImage = new RealImage(filename);
            }
            realImage.display();
        }
    }
    
    // 客戶端代碼
    public class StaticProxyExample {
        public static void main(String[] args) {
            Image image = new ImageProxy("test_image.jpg");
    
            // 第一次調(diào)用 display() 方法,會(huì)加載圖片
            image.display();
    
            // 第二次調(diào)用 display() 方法,不會(huì)再次加載圖片
            image.display();
        }
    }
    
  • JDK 動(dòng)態(tài)代理:

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    // 抽象主題
    interface Image {
        void display();
    }
    
    // 真實(shí)主題
    class RealImage implements Image {
        private String filename;
    
        public RealImage(String filename) {
            this.filename = filename;
            loadImageFromDisk();
        }
    
        private void loadImageFromDisk() {
            System.out.println("Loading image: " + filename);
        }
    
        @Override
        public void display() {
            System.out.println("Displaying image: " + filename);
        }
    }
    
    // 調(diào)用處理器
    class ImageInvocationHandler implements InvocationHandler {
        private Object target; // 被代理的對(duì)象
    
        public ImageInvocationHandler(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 在調(diào)用目標(biāo)方法之前執(zhí)行的操作
            System.out.println("Before invoking method: " + method.getName());
    
            // 調(diào)用目標(biāo)方法
            Object result = method.invoke(target, args);
    
            // 在調(diào)用目標(biāo)方法之后執(zhí)行的操作
            System.out.println("After invoking method: " + method.getName());
    
            return result;
        }
    }
    
    // 客戶端代碼
    public class JDKDynamicProxyExample {
        public static void main(String[] args) {
            // 創(chuàng)建被代理對(duì)象
            Image realImage = new RealImage("test_image.jpg");
    
            // 創(chuàng)建調(diào)用處理器
            ImageInvocationHandler handler = new ImageInvocationHandler(realImage);
    
            // 創(chuàng)建代理對(duì)象
            Image proxy = (Image) Proxy.newProxyInstance(
                    Image.class.getClassLoader(), // 類加載器
                    new Class[] {Image.class}, // 代理類實(shí)現(xiàn)的接口列表
                    handler // 調(diào)用處理器
            );
    
            // 通過(guò)代理對(duì)象調(diào)用方法
            proxy.display();
        }
    }
    
  • CGLIB 動(dòng)態(tài)代理:

    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    // 真實(shí)主題 (不需要實(shí)現(xiàn)接口)
    class RealImage {
        private String filename;
    
        public RealImage(String filename) {
            this.filename = filename;
            loadImageFromDisk();
        }
        public RealImage(){} //需要一個(gè)無(wú)參構(gòu)造函數(shù)
    
        private void loadImageFromDisk() {
            System.out.println("Loading image: " + filename);
        }
    
        public void display() {
            System.out.println("Displaying image: " + filename);
        }
    }
    
    // 方法攔截器
    class ImageMethodInterceptor implements MethodInterceptor {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            // 在調(diào)用目標(biāo)方法之前執(zhí)行的操作
            System.out.println("Before invoking method: " + method.getName());
    
            // 調(diào)用目標(biāo)方法
            Object result = proxy.invokeSuper(obj, args);
    
            // 在調(diào)用目標(biāo)方法之后執(zhí)行的操作
            System.out.println("After invoking method: " + method.getName());
    
            return result;
        }
    }
    
    // 客戶端代碼
    public class CGLIBDynamicProxyExample {
        public static void main(String[] args) {
            // 創(chuàng)建 Enhancer 對(duì)象
            Enhancer enhancer = new Enhancer();
    
            // 設(shè)置超類
            enhancer.setSuperclass(RealImage.class);
    
            // 設(shè)置回調(diào)
            enhancer.setCallback(new ImageMethodInterceptor());
    
            // 創(chuàng)建代理對(duì)象
            RealImage proxy = (RealImage) enhancer.create();
    
            // 通過(guò)代理對(duì)象調(diào)用方法
            proxy.display();
        }
    }
    

五、代理模式的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  • 職責(zé)清晰: 將客戶端與目標(biāo)對(duì)象分離,降低了耦合度。
  • 擴(kuò)展性好: 可以通過(guò)添加新的代理類來(lái)擴(kuò)展系統(tǒng)功能,而無(wú)需修改原始代碼。
  • 保護(hù)目標(biāo)對(duì)象: 代理對(duì)象可以控制對(duì)目標(biāo)對(duì)象的訪問(wèn),保護(hù)目標(biāo)對(duì)象免受惡意訪問(wèn)。
  • 增強(qiáng)目標(biāo)對(duì)象的功能: 代理對(duì)象可以在訪問(wèn)目標(biāo)對(duì)象前后添加額外的操作,例如日志記錄、安全檢查、延遲加載等。

缺點(diǎn):

  • 增加系統(tǒng)復(fù)雜性: 引入代理對(duì)象會(huì)增加系統(tǒng)的復(fù)雜性。
  • 可能降低性能: 代理對(duì)象需要進(jìn)行額外的處理,可能會(huì)降低程序的性能。

六、代理模式的應(yīng)用場(chǎng)景

  • 遠(yuǎn)程代理 (Remote Proxy): 為遠(yuǎn)程對(duì)象提供一個(gè)本地代理,隱藏遠(yuǎn)程對(duì)象的具體實(shí)現(xiàn)細(xì)節(jié)。
  • 虛擬代理 (Virtual Proxy): 為創(chuàng)建開(kāi)銷大的對(duì)象提供一個(gè)代理,延遲對(duì)象的創(chuàng)建,直到真正需要使用時(shí)才創(chuàng)建。
  • 保護(hù)代理 (Protection Proxy): 控制對(duì)敏感對(duì)象的訪問(wèn),只允許具有特定權(quán)限的客戶端訪問(wèn)。
  • 緩存代理 (Cache Proxy): 為訪問(wèn)開(kāi)銷大的對(duì)象提供一個(gè)緩存,提高訪問(wèn)效率。
  • 智能引用代理 (Smart Reference Proxy): 在訪問(wèn)對(duì)象時(shí)執(zhí)行額外的操作,例如引用計(jì)數(shù)、對(duì)象鎖定等。
  • AOP (面向切面編程): 使用動(dòng)態(tài)代理來(lái)實(shí)現(xiàn) AOP,例如 Spring AOP。
  • 延遲加載 (Lazy Loading): 例如,Hibernate 中的延遲加載機(jī)制。
  • 防火墻代理: 控制網(wǎng)絡(luò)訪問(wèn),保護(hù)內(nèi)部網(wǎng)絡(luò)。

七、總結(jié)

代理模式是一種非常有用的設(shè)計(jì)模式,它可以控制對(duì)對(duì)象的訪問(wèn),并可以在訪問(wèn)前后添加額外的操作。 在 Java 中,可以使用靜態(tài)代理、JDK 動(dòng)態(tài)代理和 CGLIB 動(dòng)態(tài)代理來(lái)實(shí)現(xiàn)代理模式。 選擇哪種實(shí)現(xiàn)方式取決于具體的應(yīng)用場(chǎng)景和需求。

到此這篇關(guān)于Java代理模式(Proxy)實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)Java代理模式Proxy內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springMvc異步的DeferredResult long?polling應(yīng)用示例解析

    springMvc異步的DeferredResult long?polling應(yīng)用示例解析

    這篇文章主要為大家介紹了springMvc中DeferredResult的long?polling應(yīng)用示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • nacos單機(jī)本地配置文件存儲(chǔ)位置方式

    nacos單機(jī)本地配置文件存儲(chǔ)位置方式

    這篇文章主要介紹了nacos單機(jī)本地配置文件存儲(chǔ)位置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • springboot的@Value中#和$區(qū)別詳解

    springboot的@Value中#和$區(qū)別詳解

    這篇文章主要介紹了springboot的@Value中#和$區(qū)別詳解,@Value注解的作用主要可以給屬性直接賦值、也可以讀取配置文件中的值給屬性賦值,需要的朋友可以參考下
    2023-11-11
  • SpringBoot中異常處理實(shí)戰(zhàn)記錄

    SpringBoot中異常處理實(shí)戰(zhàn)記錄

    在我們實(shí)際項(xiàng)目開(kāi)放中經(jīng)常需要我們處理很多的異常,如何在spring boot項(xiàng)目里面實(shí)現(xiàn)異常處理呢,下面這篇文章主要給大家介紹了關(guān)于SpringBoot中異常處理的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • 深入理解Hibernate中的flush機(jī)制

    深入理解Hibernate中的flush機(jī)制

    這篇文章主要介紹了深入理解Hibernate中的flush機(jī)制,本文是對(duì)flush機(jī)制深入研究得出的一些結(jié)論總結(jié),需要的朋友可以參考下
    2015-01-01
  • Java?超詳細(xì)講解十大排序算法面試無(wú)憂

    Java?超詳細(xì)講解十大排序算法面試無(wú)憂

    這篇文章主要介紹了Java常用的排序算法及代碼實(shí)現(xiàn),在Java開(kāi)發(fā)中,對(duì)排序的應(yīng)用需要熟練的掌握,這樣才能夠確保Java學(xué)習(xí)時(shí)候能夠有扎實(shí)的基礎(chǔ)能力。那Java有哪些排序算法呢?本文小編就來(lái)詳細(xì)說(shuō)說(shuō)Java常見(jiàn)的排序算法,需要的朋友可以參考一下
    2022-04-04
  • 解析java中This的用法分析

    解析java中This的用法分析

    本篇文章是對(duì)java中This的用法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 解決未解析的依賴項(xiàng):‘net.sf.json-lib:json-lib:jar:2.4‘問(wèn)題

    解決未解析的依賴項(xiàng):‘net.sf.json-lib:json-lib:jar:2.4‘問(wèn)題

    這篇文章主要介紹了解決未解析的依賴項(xiàng):‘net.sf.json-lib:json-lib:jar:2.4‘問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • Java或kafka_tool連接不上虛擬機(jī)的kafka問(wèn)題及解決

    Java或kafka_tool連接不上虛擬機(jī)的kafka問(wèn)題及解決

    文章介紹了如何配置防火墻端口、修改config/server.properties文件以及配置kafka_tool,并分享了個(gè)人經(jīng)驗(yàn)
    2026-01-01
  • 把Jar文件轉(zhuǎn)成exe安裝文件的實(shí)現(xiàn)方法

    把Jar文件轉(zhuǎn)成exe安裝文件的實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇把Jar文件轉(zhuǎn)成exe安裝文件的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-11-11

最新評(píng)論

湖南省| 昌乐县| 青海省| 辛集市| 上犹县| 策勒县| 色达县| 明星| 兖州市| 巧家县| 铁力市| 颍上县| 翼城县| 嵊州市| 全南县| 宝丰县| 鲁山县| 景德镇市| 祁阳县| 托克逊县| 乌拉特后旗| 平遥县| 石台县| 永济市| 大足县| 镇坪县| 革吉县| 绥江县| 甘洛县| 宾川县| 屯昌县| 乌拉特中旗| 嘉兴市| 溆浦县| 新乡市| 平阳县| 平利县| 什邡市| 乌拉特前旗| 新密市| 饶平县|