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

Java結(jié)構(gòu)型設(shè)計(jì)模式中代理模式示例詳解

 更新時(shí)間:2022年09月22日 16:25:28   作者:丨Jack_Chen丨  
代理模式(Proxy Parttern)為一個(gè)對(duì)象提供一個(gè)替身,來(lái)控制這個(gè)對(duì)象的訪問(wèn),即通過(guò)代理對(duì)象來(lái)訪問(wèn)目標(biāo)對(duì)象。本文將通過(guò)示例詳細(xì)講解一下這個(gè)模式,需要的可以參考一下

代理模式

代理模式(Proxy Pattern)屬于結(jié)構(gòu)型模式。

它是指為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。

在某些情況下,一個(gè)對(duì)象不適合或者不能直接引用另一個(gè)對(duì)象,而代理對(duì)象可以在客戶端和目標(biāo)對(duì)象之間起到中介的作用。

在代理模式中,創(chuàng)建具有現(xiàn)有對(duì)象的對(duì)象,以便向外界提供功能接口。

想在訪問(wèn)一個(gè)類時(shí)做一些控制的時(shí)候就可以是用代理模式。

分類

代理模式屬于結(jié)構(gòu)型模式,分為靜態(tài)代理和動(dòng)態(tài)代理。

1.靜態(tài)代理:靜態(tài)定義代理類

靜態(tài)代理需要自己生成代理類

2.動(dòng)態(tài)代理:動(dòng)態(tài)生成代理類

動(dòng)態(tài)代理不用親自去實(shí)現(xiàn),通常使用現(xiàn)成的API即可。目前普遍使用的是JDK自帶的代理與CGLIB提供的類庫(kù)。

主要角色

代理模式一般包含三種角色:

1.抽象主題角色(Subject)

抽象主題類的主要職責(zé)是聲明真實(shí)主題與代理的共同接口方法,該類可以是接口也可以是抽象類

2.真實(shí)主題角色(RealSubject)

該類也被稱為被代理類,該類定義了代理所表示的真實(shí)對(duì)象,是負(fù)責(zé)執(zhí)行系統(tǒng)真正的羅輯業(yè)務(wù)對(duì)象

3.代理主題角色(Proxy)

代理主題也被稱為代理類,其內(nèi)部特有RealSubject的引用,因此具備完全的對(duì)RealSubject的代理權(quán)。

客戶端調(diào)用代理對(duì)象的方法,同時(shí)也調(diào)用被代理對(duì)象的方法,但是會(huì)在代理對(duì)象前后增加一些處理代碼??梢岳斫鉃榇a增強(qiáng),實(shí)際上就是在原代碼羅輯前后增加一些代碼邏輯,而使調(diào)用者無(wú)感知。

作用

1.保護(hù)目標(biāo)對(duì)象,將代理對(duì)象與真實(shí)被調(diào)用目標(biāo)對(duì)象分離

2.增強(qiáng)目標(biāo)對(duì)象

3.降低系統(tǒng)耦合性,提升擴(kuò)展性

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

1.靜態(tài)代理只能通過(guò)手動(dòng)完成代理操作,如果被代理類增加了新的方法,代理類需要同步增加,違背開(kāi)閉原則。

2.動(dòng)態(tài)代理采用在運(yùn)行時(shí)動(dòng)態(tài)生成代碼的方式,取消了對(duì)被代理類的擴(kuò)展限制,遵循開(kāi)閉原測(cè)。

3.若動(dòng)態(tài)代理要對(duì)目標(biāo)類的增強(qiáng)邏輯進(jìn)行擴(kuò)展,結(jié)合策略模式,只需要新增策略類便可完成,無(wú)須修改代理類的代碼。

靜態(tài)代理的基本使用

靜態(tài)代理需要自己生成代理類

創(chuàng)建抽象主題

public interface ISubject {
    /**
     * 買票
     */
    void buyTickets();
}

創(chuàng)建真實(shí)主題

public class RealSubject implements ISubject {
    public void buyTickets() {
        System.out.println("進(jìn)行買票操作");
    }
}

創(chuàng)建代理主題

public class Proxy implements ISubject {
    private ISubject subject;
    public Proxy(ISubject subject) {
        this.subject = subject;
    }
    public void buyTickets() {
        before();
        subject.buyTickets();
        after();
    }
    public void before() {
        System.out.println("買票前的操作");
    }
    public void after() {
        System.out.println("買票后的操作");
    }
}

客戶端調(diào)用

    public static void main(String[] args) {
        Proxy proxy = new Proxy(new RealSubject());
        proxy.buyTickets();
    }

買票前的操作
進(jìn)行買票操作
買票后的操作

JDK動(dòng)態(tài)代理的基本使用

創(chuàng)建抽象主題

public interface IUser {
    /**
     * 購(gòu)物
     */
    void shopping();
}

創(chuàng)建真實(shí)主題

public class User implements IUser{
    @Override
    public void shopping() {
        System.out.println("user shopping....");
    }
}

創(chuàng)建代理主題

public class JDKProxy implements InvocationHandler {
    private Object tarjet;
    public JDKProxy(Object tarjet) {
        this.tarjet = tarjet;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理user,執(zhí)行shopping()開(kāi)始...");
        Object oj = method.invoke(tarjet, args);
        System.out.println("代理user,執(zhí)行shopping()結(jié)束...");
        return oj;
    }
}

客戶端調(diào)用

    public static void main(String[] args) {
        User user = new User();
        JDKProxy jdkProxy = new JDKProxy(user);
        IUser proxyInstance = (IUser) Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(), jdkProxy);
        proxyInstance.shopping();
    }

代理user,執(zhí)行shopping()開(kāi)始...
user shopping....
代理user,執(zhí)行shopping()結(jié)束...

小優(yōu)化

在調(diào)用時(shí)候,傳入了一推參數(shù),可進(jìn)一步優(yōu)化

public class JDKProxy implements InvocationHandler {
    private Object tarjet;
    public Object JDKProxy(Object target){
        this.tarjet = target;
        Class<?> clazz =  target.getClass();
        return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理user,執(zhí)行shopping()開(kāi)始...");
        Object oj = method.invoke(tarjet, args);
        System.out.println("代理user,執(zhí)行shopping()結(jié)束...");
        return oj;
    }
}
    public static void main(String[] args) {
        JDKProxy jdkProxy = new JDKProxy();
        IUser user= (IUser)jdkProxy.JDKProxy(new User());
        user.shopping();
    }

CGLIB動(dòng)態(tài)代理的基本使用

CGLIB動(dòng)態(tài)代理也不需要生成代理類,實(shí)現(xiàn)MethodInterceptor 就可以了。

注意:CGLib不能代理final的方法

創(chuàng)建抽象主題

注意:CGLb代理的目標(biāo)對(duì)象不需要實(shí)現(xiàn)任何接口,就可以通過(guò)動(dòng)態(tài)繼承目標(biāo)對(duì)象實(shí)現(xiàn)動(dòng)態(tài)代理。所以此處可以不用創(chuàng)建接口。直接使用真實(shí)主題。

public interface IUser {
    public void shopping();
}

創(chuàng)建真實(shí)主題

public class User implements IUser{
    @Override
    public void shopping() {
        System.out.println("user shopping....");
    }
}

直接使用真實(shí)主題。

public class User {
    public void shopping() {
        System.out.println("user shopping....");
    }
}

創(chuàng)建代理主題

public class CglibProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("代理user,執(zhí)行shopping()開(kāi)始...");
        Object invokeSuper = methodProxy.invokeSuper(o, objects);
        System.out.println("代理user,執(zhí)行shopping()結(jié)束...");
        return invokeSuper;
    }
}

客戶端調(diào)用

    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(User.class);
        enhancer.setCallback(cglibProxy);
        IUser iUser = (IUser) enhancer.create();
        iUser.shopping();
    }

小優(yōu)化

在客戶端調(diào)用時(shí),稍顯復(fù)雜,可進(jìn)一步優(yōu)化

public class CglibProxy implements MethodInterceptor {
    public Object getInstance(Class<?> clazz) throws Exception{
        //相當(dāng)于Proxy,代理工具類
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("代理user,執(zhí)行shopping()開(kāi)始...");
        Object invokeSuper = methodProxy.invokeSuper(o, objects);
        System.out.println("代理user,執(zhí)行shopping()結(jié)束...");
        return invokeSuper;
    }
}
    public static void main(String[] args) throws Exception {
        IUser user = (IUser) new CglibProxy().getInstance(User.class);
        user.shopping();
    }

CGLIB與JDK動(dòng)態(tài)代理區(qū)別

1.執(zhí)行條件

JDK動(dòng)態(tài)代理實(shí)現(xiàn)了被代理對(duì)象的接口。CGLb代理的目標(biāo)對(duì)象不需要實(shí)現(xiàn)任何接口,它是通過(guò)動(dòng)態(tài)繼承目標(biāo)對(duì)象實(shí)現(xiàn)動(dòng)態(tài)代理。

2.實(shí)現(xiàn)機(jī)制

JDK動(dòng)態(tài)代理調(diào)用代理方法是由Java內(nèi)部的反射機(jī)制來(lái)實(shí)現(xiàn)的,需要讀取接口信息。CGLib動(dòng)態(tài)代理是通過(guò)FastClass機(jī)制來(lái)實(shí)現(xiàn)的,需要覆蓋父類方法。

3.性能

首先都在運(yùn)行期生成字節(jié)碼。

JDK動(dòng)態(tài)代理的代理邏輯簡(jiǎn)單,直接寫(xiě)Class字節(jié)碼,使用反射機(jī)制在生成類的過(guò)程中比較高效。

CGLib代理實(shí)現(xiàn)更復(fù)雜,使用ASM框架寫(xiě)Class字節(jié)碼,但是asm在生成類之后的相關(guān)執(zhí)行過(guò)程中比較高效。但是可以通過(guò)將asm生成的類進(jìn)行緩存,解決asm生成類過(guò)程低效問(wèn)題。

一句話:CGLib生成代理類比JDK動(dòng)態(tài)代理效率低,但是執(zhí)行效率比JDK動(dòng)態(tài)代理高。

到此這篇關(guān)于Java結(jié)構(gòu)型設(shè)計(jì)模式中代理模式示例詳解的文章就介紹到這了,更多相關(guān)Java代理模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • idea 默認(rèn)路徑修改從C盤更改到D盤

    idea 默認(rèn)路徑修改從C盤更改到D盤

    本文主要介紹了idea 默認(rèn)路徑修改從C盤更改到D盤,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07
  • 基于Spring監(jiān)聽(tīng)Binlog日志的方法詳解

    基于Spring監(jiān)聽(tīng)Binlog日志的方法詳解

    MySQL 的二進(jìn)制日志(binlog)有三種不同的格式,通常被稱為 binlog 模式,這三種模式分別是 Statement 模式、Row 模式和Mixed 模式,本文將給大家介紹如何基于Spring監(jiān)聽(tīng)Binlog日志,需要的朋友可以參考下
    2024-09-09
  • 你應(yīng)該知道的java中的5個(gè)注解

    你應(yīng)該知道的java中的5個(gè)注解

    自Java5.0版本引入注解之后,它就成為了Java平臺(tái)中非常重要的一部分。開(kāi)發(fā)過(guò)程中,我們也時(shí)常在應(yīng)用代碼中會(huì)看到像@Override,@Deprecated這樣的注解。下面小編和大家來(lái)一起學(xué)習(xí)一下吧
    2019-05-05
  • Java中序列化與反序列化的特性解讀

    Java中序列化與反序列化的特性解讀

    這篇文章主要介紹了Java中序列化與反序列化的特性解讀,當(dāng)我們需要將內(nèi)存中的對(duì)象持久化到磁盤,數(shù)據(jù)庫(kù)中時(shí), 當(dāng)我們需要與瀏覽器進(jìn)行交互時(shí),當(dāng)我們需要實(shí)現(xiàn) RPC 時(shí), 這個(gè)時(shí)候就需要序列化和反序列化了,需要的朋友可以參考下
    2023-08-08
  • Java計(jì)算一個(gè)數(shù)加上100是完全平方數(shù),加上168還是完全平方數(shù)

    Java計(jì)算一個(gè)數(shù)加上100是完全平方數(shù),加上168還是完全平方數(shù)

    這篇文章主要介紹了Java計(jì)算一個(gè)數(shù)加上100是完全平方數(shù),加上168還是完全平方數(shù),需要的朋友可以參考下
    2017-02-02
  • java使用poi讀取doc和docx文件的實(shí)現(xiàn)示例

    java使用poi讀取doc和docx文件的實(shí)現(xiàn)示例

    這篇文章主要介紹了java使用poi讀取doc和docx文件的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Java基礎(chǔ)之二叉搜索樹(shù)的基本操作

    Java基礎(chǔ)之二叉搜索樹(shù)的基本操作

    發(fā)現(xiàn)許多小伙伴還不清楚Java二叉搜索樹(shù)的基本操作,今天特地整理了這篇文章,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)Java的小伙伴很有幫助,需要的朋友可以參考下
    2021-05-05
  • java 按行讀取文件并輸出到控制臺(tái)的方法

    java 按行讀取文件并輸出到控制臺(tái)的方法

    今天小編就為大家分享一篇java 按行讀取文件并輸出到控制臺(tái)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Java字符串拼接+和StringBuilder的比較與選擇

    Java字符串拼接+和StringBuilder的比較與選擇

    Java 提供了兩種主要的方式:使用 "+" 運(yùn)算符和使用 StringBuilder 類,本文主要介紹了Java字符串拼接+和StringBuilder的比較與選擇,感興趣的可以了解一下
    2023-10-10
  • 一段眼睛跟著鼠標(biāo)轉(zhuǎn)動(dòng)的跟蹤眼代碼

    一段眼睛跟著鼠標(biāo)轉(zhuǎn)動(dòng)的跟蹤眼代碼

    java實(shí)現(xiàn)的眼睛跟著鼠標(biāo)轉(zhuǎn)動(dòng)的跟蹤眼代碼
    2008-10-10

最新評(píng)論

肃北| 商城县| 布尔津县| 靖江市| 石家庄市| 金山区| 惠州市| 鄯善县| 沁水县| 环江| 万山特区| 甘南县| 翁源县| 丹寨县| 安陆市| 山丹县| 增城市| 泽普县| 定襄县| 留坝县| 淳安县| 云龙县| 巴塘县| 朔州市| 永泰县| 娄底市| 连江县| 娄底市| 象州县| 清镇市| 子洲县| 中宁县| 新和县| 广河县| 公安县| 三穗县| 江油市| 芦山县| 锦屏县| 额敏县| 黔南|