国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

設(shè)計(jì)模式二:代理模式

這篇具有很好參考價(jià)值的文章主要介紹了設(shè)計(jì)模式二:代理模式。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

1、什么是動(dòng)態(tài)代理

設(shè)計(jì)模式二:代理模式,設(shè)計(jì)模式,代理模式

可能很多小伙伴首次接觸動(dòng)態(tài)代理這個(gè)名詞的時(shí)候,或者是在面試過(guò)程中被問(wèn)到動(dòng)態(tài)代理的時(shí)候,不能很好的描述出來(lái),動(dòng)態(tài)代理到底是個(gè)什么高大上的技術(shù)。不方,其實(shí)動(dòng)態(tài)代理的使用非常廣泛,例如我們平常使用的 Spring中的 @Transactional注解,其依賴(lài)于 AOP,而 AOP的底層實(shí)現(xiàn)便是動(dòng)態(tài)代理,看到這里,是不是更有興趣去了解動(dòng)態(tài)代理了呢?

動(dòng)態(tài)代理:可以分解為"動(dòng)態(tài)"+“代理”。

  • 代理:"代理"一詞,在我們的生活中也是隨處可見(jiàn)的,例如房屋中介,其是對(duì)房主的一種代理,房主需要出租其房屋,但是可能沒(méi)時(shí)間去接待租客,給租客介紹房屋信息,帶領(lǐng)租客看房,但是房屋中介可以為租客提供這些服務(wù),所以,代理其是對(duì)被代理對(duì)象的一個(gè)功能增強(qiáng)
  • 動(dòng)態(tài):"動(dòng)態(tài)"通常與"靜態(tài)"相比較,"靜態(tài)"描述的是事物是固定存在的,"動(dòng)態(tài)"則描述的是事物是隨著需求而動(dòng)態(tài)生成的。

所以,靜態(tài)代理存在一定的局限性,不能很好的滿(mǎn)足需求的千變?nèi)f化,動(dòng)態(tài)代理的出現(xiàn),就是為了解決這些局限性。

我們先來(lái)看看靜態(tài)代理。

2.、靜態(tài)代理

在開(kāi)發(fā)中,通常需要為方法添加日志打印,能夠記錄程序的執(zhí)行過(guò)程,以便后續(xù)出現(xiàn)異常問(wèn)題的時(shí)候,能更好的排查定位。

假設(shè)我們現(xiàn)在已經(jīng)完成了系統(tǒng)用戶(hù)的增加、刪除、修改等功能,這些功能在類(lèi) UserServiceImpl中已經(jīng)實(shí)現(xiàn)。

代碼示例:

public class UserServiceImpl {
    public void add() {
        System.out.println("添加用戶(hù)");
    }
    
    public void update() {
        System.out.println("修改用戶(hù)");
    }

    public void delete() {
        System.out.println("刪除用戶(hù)");
    }
}

現(xiàn)在,我們需要在UserServiceImpl類(lèi)中的方法添加日志功能,那么怎么才能更好地去實(shí)現(xiàn)這個(gè)需求呢?

1)直接在目標(biāo)方法前后添加日志代碼

代碼示例:

public class UserServiceImpl {
    public void add() {
        System.out.println("====== add方法開(kāi)始 ======");
        System.out.println("添加用戶(hù)");
        System.out.println("====== add方法結(jié)束 ======");
    }
?
    public void update() {
        System.out.println("====== update方法開(kāi)始 ======");
        System.out.println("修改用戶(hù)");
        System.out.println("====== update方法結(jié)束 ======");
    }
?
    public void delete() {
        System.out.println("====== delete方法開(kāi)始 ======");
        System.out.println("刪除用戶(hù)");
        System.out.println("====== delete方法結(jié)束 ======");
    }
}

觀察上述代碼,這種方式的缺點(diǎn)在于:

2)靜態(tài)代理方式實(shí)現(xiàn)

靜態(tài)代理需要我們將目標(biāo)類(lèi)的方法抽取到接口中,代理類(lèi)和目標(biāo)類(lèi)實(shí)現(xiàn)同一個(gè)接口,既然要實(shí)現(xiàn)代理,代理類(lèi)自然需要在其內(nèi)部維護(hù)目標(biāo)對(duì)象的引用,并通過(guò)構(gòu)造函數(shù)為其賦值,然后在代理類(lèi)的方法中調(diào)用目標(biāo)對(duì)象的同名方法,并在調(diào)用前后完成功能的增強(qiáng)。

實(shí)現(xiàn)步驟:

  • 抽取UserService接口
  • 創(chuàng)建目標(biāo)類(lèi)UserServiceImpl實(shí)現(xiàn)UserService接口
  • 創(chuàng)建代理類(lèi)UserServiceProxy實(shí)現(xiàn)UserService接口
  • 代理類(lèi)中完成功能的增強(qiáng)

代碼實(shí)現(xiàn):

// 目標(biāo)接口
public interface UserService {
    void add();

    void update();

    void delete();
}
// 目標(biāo)類(lèi)
public class UserServiceImpl implements UserService {
    @Override
    public void add() {
        System.out.println("添加用戶(hù)");
    }

    @Override
    public void update() {
        System.out.println("修改用戶(hù)");
    }

    @Override
    public void delete() {
        System.out.println("刪除用戶(hù)");
    }
}
// 代理類(lèi)
public class UserServiceProxy implements UserService {

    private UserService userService;

    public UserServiceProxy(UserService userService) {
        this.userService = userService;
    }

    @Override
    public void add() {
        System.out.println("====== add方法開(kāi)始 ======");
        userService.add();
        System.out.println("====== add方法結(jié)束 ======");
    }

    @Override
    public void update() {
        System.out.println("====== update方法開(kāi)始 ======");
        userService.update();
        System.out.println("====== update方法結(jié)束 ======");
    }

    @Override
    public void delete() {
        System.out.println("====== delete方法開(kāi)始 ======");
        userService.delete();
        System.out.println("====== delete方法結(jié)束 ======");
    }
}

觀察上述代碼,靜態(tài)代理遵循開(kāi)閉原則,在不修改目標(biāo)類(lèi)的前提下,完成了功能的增強(qiáng),但是依然存在大量重復(fù)的代碼,且一個(gè)代理類(lèi)只能代理一個(gè)目標(biāo)類(lèi),如果有n個(gè)目標(biāo)類(lèi)需要被代理,就需要同比增加n個(gè)代理類(lèi)。

那么,有沒(méi)有辦法可以使得我們不需要去定義這么多的代理類(lèi),就可以實(shí)現(xiàn)對(duì)目標(biāo)類(lèi)功能的增強(qiáng)?答案是有的:動(dòng)態(tài)代理。

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

前面,我們提到靜態(tài)代理的實(shí)現(xiàn)方式:代理類(lèi)和目標(biāo)類(lèi)都實(shí)現(xiàn)同一個(gè)接口,在代理類(lèi)中維護(hù)目標(biāo)類(lèi)對(duì)象,并完成對(duì)目標(biāo)類(lèi)對(duì)象方法的增強(qiáng),這種方式雖然遵循開(kāi)閉原則,但是代理類(lèi)和目標(biāo)類(lèi)至少是"一對(duì)一"的綁定關(guān)系,如果需要被代理的目標(biāo)類(lèi)個(gè)數(shù)越多,代理類(lèi)就會(huì)越多,會(huì)產(chǎn)生大量重復(fù)的代碼,也不利于后期的維護(hù)。

從靜態(tài)代理中,我們知道代理類(lèi)也是接口的一個(gè)實(shí)現(xiàn)類(lèi),代理對(duì)象的類(lèi)型也是屬于接口類(lèi)型,我們來(lái)驗(yàn)證一下。

public class Test {
    public static void main(String[] args) {
        UserServiceProxy userServiceProxy = new UserServiceProxy(new UserServiceImpl());
        System.out.println(userServiceProxy instanceof UserService);
    }
}
// 打印結(jié)果:true

那么,能不能動(dòng)態(tài)生成這些代理對(duì)象呢?我們知道類(lèi)是構(gòu)造對(duì)象的模板,代理類(lèi)都還不存在,怎么去構(gòu)造代理對(duì)象呢?

除了不存在代理類(lèi),還剩下 UserService接口和 UserServiceImpl目標(biāo)類(lèi),JDK動(dòng)態(tài)代理的目的就是通過(guò)接口來(lái)生成代理類(lèi)以及代理類(lèi)的對(duì)象,我們知道接口是不能直接通過(guò)new關(guān)鍵字創(chuàng)建對(duì)象的。

那么JDK動(dòng)態(tài)代理是怎么創(chuàng)建出代理類(lèi)以及代理類(lèi)對(duì)象的呢?

我們先來(lái)看看通過(guò) new關(guān)鍵字創(chuàng)建對(duì)象的過(guò)程。

UserServiceImpl userService = new UserServiceImpl();
/*
創(chuàng)建對(duì)象的過(guò)程:
    1.執(zhí)行new指令,如果類(lèi)未加載,先執(zhí)行類(lèi)加載過(guò)程。
        1.加載:JVM通過(guò)ClassLoader將UserServiceImpl.class文件加載到方法區(qū)(Method Area),在堆內(nèi)存中創(chuàng)建代表該類(lèi)的Class對(duì)象。
        2.驗(yàn)證
        3.準(zhǔn)備:為靜態(tài)變量分配內(nèi)存并設(shè)置類(lèi)型初始值。
        4.解析
        5.初始化:為靜態(tài)變量賦值、執(zhí)行靜態(tài)代碼塊
    2.為對(duì)象分配內(nèi)存,將對(duì)象的實(shí)例字段初始化類(lèi)型零值。
    3.執(zhí)行構(gòu)造方法,對(duì)對(duì)象進(jìn)行初始化
*/

設(shè)計(jì)模式二:代理模式,設(shè)計(jì)模式,代理模式

追蹤上述過(guò)程,我們得知?jiǎng)?chuàng)建對(duì)象,需要先得到該類(lèi)的Class對(duì)象,通過(guò)Class對(duì)象去創(chuàng)建實(shí)例對(duì)象。為了驗(yàn)證這一點(diǎn),我們不妨來(lái)看看通過(guò)反射的方式創(chuàng)建對(duì)象的過(guò)程。

public class Test {
    @SneakyThrows
    public static void main(String[] args) {
        // 獲取Class對(duì)象
        Class<UserServiceImpl> userServiceClass = UserServiceImpl.class;
        // 獲取構(gòu)造器
        Constructor<?>[] constructors = userServiceClass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            // 通過(guò)構(gòu)造器創(chuàng)建實(shí)例對(duì)象
            System.out.println(constructor.newInstance());
        }
    }
}

現(xiàn)在,問(wèn)題回歸到接口不能直接new,也沒(méi)有構(gòu)造方法,并且不存在代理類(lèi)的class文件,怎么獲得Class對(duì)象了。

動(dòng)態(tài)代理關(guān)鍵類(lèi)

我們先來(lái)看看JDK動(dòng)態(tài)代理的實(shí)戰(zhàn)代碼:

  • 需要自定義個(gè) CustomInvocationHandler實(shí)現(xiàn) InvocationHandler接口。
  • 利用 Proxy.newProxyInstance構(gòu)建實(shí)例對(duì)象。
// UserService接口
public interface UserService {
    void add();

    void update();

    void delete();
}

// 目標(biāo)類(lèi)
public class UserServiceImpl implements UserService {
    @Override
    public void add() {
        System.out.println("添加用戶(hù)");
    }

    @Override
    public void update() {
        System.out.println("修改用戶(hù)");
    }

    @Override
    public void delete() {
        System.out.println("刪除用戶(hù)");
    }
}

// CustomInvocationHandler
public class CustomInvocationHandler implements InvocationHandler {

    // 目標(biāo)對(duì)象
    private Object target;

    public CustomInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("====== 方法開(kāi)始 ======");
        Object result = method.invoke(target, args);
        System.out.println("====== 方法結(jié)束 ======");
        return result;
    }
}

public class Test {
    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();
        // 關(guān)鍵代碼
        UserService service = (UserService) Proxy.newProxyInstance(UserServiceImpl.class.getClassLoader(), UserServiceImpl.class.getInterfaces(), new CustomInvocationHandler(userService));
        service.add();
    }
}

設(shè)計(jì)模式二:代理模式,設(shè)計(jì)模式,代理模式

從測(cè)試代碼可以看出,Proxy類(lèi)是關(guān)鍵。我們來(lái)看看Proxy為我們提供的方法:

Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces)雖然被標(biāo)注為過(guò)時(shí)方法,但是從名字上可以得知,其目的是為了獲得代理類(lèi)的Class對(duì)象。話不多說(shuō),我們來(lái)調(diào)用一下。

public class Test {
    public static void main(String[] args) {
        Class<?> proxyClass = Proxy.getProxyClass(UserServiceImpl.class.getClassLoader(), UserServiceImpl.class.getInterfaces());
        System.out.println(proxyClass.getName());
        for (Method method : proxyClass.getDeclaredMethods()) {
            System.out.println(method.getDeclaringClass() + "." + method.getName() + "()");
        }
        System.out.println(Arrays.toString(proxyClass.getConstructors()));
    }
}

設(shè)計(jì)模式二:代理模式,設(shè)計(jì)模式,代理模式

可以看到:

  • 獲得的Class對(duì)象的名稱(chēng)為 $Proxy0。
  • 定義了我們需要的 add();update();delete()方法。
  • 定義了一個(gè)有參構(gòu)造方法 $Proxy0(InvocationHandler handler)。

雖然沒(méi)有無(wú)參構(gòu)造方法,我們還是得嘗試一下調(diào)用一下這個(gè)有參的構(gòu)造方法,需要我們傳入一個(gè) java.lang.reflect.InvocationHandler對(duì)象

public class Test {
    @SneakyThrows
    public static void main(String[] args) {
        System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true");
        Class<?> proxyClass = Proxy.getProxyClass(UserServiceImpl.class.getClassLoader(), UserServiceImpl.class.getInterfaces());
        // 獲取$Proxy0(InvocationHandler handler)構(gòu)造方法
        Constructor<?> constructor = proxyClass.getConstructor(InvocationHandler.class);
        UserService userService = (UserService) constructor.newInstance(new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(proxy.getClass());
                System.out.println(method.getDeclaringClass() + "." + method.getName() + "()");
                return null;
            }
        });
        userService.add();
    }
}

設(shè)計(jì)模式二:代理模式,設(shè)計(jì)模式,代理模式

看的出來(lái),**當(dāng)我們獲得代理對(duì)象之后,通過(guò)代理對(duì)象來(lái)調(diào)用接口方法,都會(huì)回調(diào)構(gòu)造時(shí)傳進(jìn)來(lái)的 InvocationHandler對(duì)象的 invoke(Object proxy, Method method, Object[] args)方法,**該方法有3個(gè)參數(shù):

  • Object proxy:代表的是代理對(duì)象本身。
  • Method method:代表的是被調(diào)用的方法的Method對(duì)象。
  • Object[] args:代表的是被調(diào)用方法的參數(shù)。

可以猜測(cè),JDK動(dòng)態(tài)代理生成的代理類(lèi)中,維護(hù)了InvocationHandler類(lèi)的對(duì)象變量,并且在實(shí)現(xiàn)接口方法時(shí),通過(guò)InvocationHandler對(duì)象調(diào)用了 invoke(Object proxy, Method method, Object[] args)方法。

System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true");

不知道大家沒(méi)有看到這行代碼哈,當(dāng)添加了這行代碼之后,可以將在項(xiàng)目目錄下保存動(dòng)態(tài)創(chuàng)建的class文件, com/sun/proxy/$Proxy0.class。

設(shè)計(jì)模式二:代理模式,設(shè)計(jì)模式,代理模式

可以看到生成的代理類(lèi) $Proxy0繼承自 Proxy類(lèi),并實(shí)現(xiàn)了 UserService接口,并且在 add()方法中通過(guò)其父類(lèi) Proxy中維護(hù)的 InvocationHandler對(duì)象調(diào)用 invoke()方法,這也就成功的解釋了前面調(diào)用 userService.add()方法,會(huì)回調(diào)到invoke()方法。

這時(shí)候我們?cè)侔汛a改造一下,如下:

public class CustomInvocationHandler implements InvocationHandler {

    // 目標(biāo)對(duì)象
    private Object target;

    public CustomInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("====== 方法開(kāi)始 ======");
        Object result = method.invoke(target, args);
        System.out.println("====== 方法結(jié)束 ======");
        return result;
    }
}

public class Test {
    @SneakyThrows
    public static void main(String[] args) {
        UserServiceImpl target = new UserServiceImpl();
        Class<?> proxyClass = Proxy.getProxyClass(UserServiceImpl.class.getClassLoader(), UserServiceImpl.class.getInterfaces());
        Constructor<?> constructor = proxyClass.getConstructor(InvocationHandler.class);
        UserService userService = (UserService) constructor.newInstance(new CustomInvocationHandler(target));
        userService.add();
    }
}

這樣就完成了對(duì)目標(biāo)對(duì)象功能的增強(qiáng),前面我們提到過(guò) Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces)

已經(jīng)被標(biāo)注為過(guò)時(shí),推薦我們使用 Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法。

動(dòng)態(tài)代理設(shè)計(jì)思想

好的,到這里,我們來(lái)總結(jié)一下JDK動(dòng)態(tài)的設(shè)計(jì)思想:

設(shè)計(jì)模式二:代理模式,設(shè)計(jì)模式,代理模式

使用 JDK動(dòng)態(tài)代理,使得我們免去編寫(xiě)代理類(lèi),只需要將增強(qiáng)功能編寫(xiě)在 InvocationHandlerinvoke方法中。

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

CGLib代理的目標(biāo)對(duì)象不需要事先任何接口,它是通過(guò)動(dòng)態(tài)集成目標(biāo)對(duì)象實(shí)現(xiàn)動(dòng)態(tài)代理的。CGLib代理執(zhí)行代理方法的效率之所以比JDK高,是因?yàn)镃GLib采用了FastClass機(jī)制:為代理類(lèi)和被代理類(lèi)各生成一個(gè)類(lèi),這個(gè)類(lèi)會(huì)為代理類(lèi)或被代理類(lèi)的方法分配一個(gè)index(int類(lèi)型);這個(gè)index當(dāng)作一個(gè)入?yún)?,F(xiàn)astClass 就可以直接定位要調(diào)用的方法并直接進(jìn)行調(diào)用,省去了反射調(diào)用,所以調(diào)用效率比JDK代理通過(guò)反射調(diào)用高。FastClass并不是跟代理類(lèi)一起生成的,而是在第一次執(zhí)行MethodProxy的invoke()或invokeSuper()方法時(shí)產(chǎn)生并放在緩存中的。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-830977.html

5、CGLib和JDK動(dòng)態(tài)代理對(duì)比

  • JDK動(dòng)態(tài)代理實(shí)現(xiàn)了被代理對(duì)象的接口,CGLib代理繼承了被代理對(duì)象。
  • JDK動(dòng)態(tài)代理和CGLib代理在運(yùn)行期生成字節(jié)碼,JDK動(dòng)態(tài)代理直接寫(xiě)Class字節(jié)碼,CGLib代理使用ASM框架(字節(jié)碼操控框架)寫(xiě)Class字節(jié)碼,CGLib代理實(shí)現(xiàn)更復(fù)雜,生成代理類(lèi)比JDK動(dòng)態(tài)代理效率低。
  • JDK動(dòng)態(tài)代理調(diào)用代理方法是通過(guò)反射機(jī)制調(diào)用的,CGLib代理是通過(guò)FastClass機(jī)制直接調(diào)用方法的,CGLib代理的執(zhí)行效率更高

6、Spring中的代理選擇原則

  • 當(dāng)Bean有實(shí)現(xiàn)接口時(shí),Spring就會(huì)用JDK動(dòng)態(tài)代理
  • 當(dāng)Bean沒(méi)有實(shí)現(xiàn)接口時(shí),Spring會(huì)選擇CGLib代理
  • Spring可以通過(guò)配置強(qiáng)制使用CGLib代理,只需要在配置中加入<aop:aspectj-autoproxy roxy-target-clas=“true”>

到了這里,關(guān)于設(shè)計(jì)模式二:代理模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 設(shè)計(jì)模式詳解-代理模式

    類(lèi)型:結(jié)構(gòu)型模式 實(shí)現(xiàn)原理:創(chuàng)建具有現(xiàn)有對(duì)象的對(duì)象 作用:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。 解決的問(wèn)題:由于對(duì)象的訪問(wèn)條件不一,直接訪問(wèn)對(duì)象會(huì)造成麻煩問(wèn)題 解決問(wèn)題的方法:增加中間層。 何時(shí)使用:想在訪問(wèn)一個(gè)類(lèi)時(shí)做一些控制。 實(shí)現(xiàn)核心:

    2024年02月12日
    瀏覽(22)
  • 【設(shè)計(jì)模式】代理模式

    【設(shè)計(jì)模式】代理模式

    5.1.1 概述 由于某些原因需要給某對(duì)象提供一個(gè)代理以控制對(duì)該對(duì)象的訪問(wèn)。這時(shí),訪問(wèn)對(duì)象不適合或者不能直接引用目標(biāo)對(duì)象,代理對(duì)象作為訪問(wèn)對(duì)象和目標(biāo)對(duì)象之間的中介。 Java中的代理按照代理類(lèi)生成時(shí)機(jī)不同又分為靜態(tài)代理和動(dòng)態(tài)代理。靜態(tài)代理代理類(lèi)在編譯期就生成

    2024年02月15日
    瀏覽(31)
  • 設(shè)計(jì)模式(5)代理模式

    設(shè)計(jì)模式(5)代理模式

    一、介紹: 1、組成結(jié)構(gòu): (1)Subject/抽象角色:定義了RealSubject和Proxy的共用接口,這樣就可以在任何使用 ? ? ? ?RealSubject的地方都可以使用Proxy (2)RealSubject/真實(shí)角色:定義Proxy所代表的真實(shí)實(shí)體 (3)Proxy/代理角色:保存一個(gè)引用使得代理可以訪問(wèn)實(shí)體,并提供一個(gè)與

    2024年02月13日
    瀏覽(22)
  • 設(shè)計(jì)模式-代理模式

    ● 為對(duì)象提供一個(gè)代理類(lèi),增強(qiáng)該對(duì)象的方法,控制對(duì)這個(gè)對(duì)象的訪問(wèn) ● 靜態(tài)代理和動(dòng)態(tài)代理:靜態(tài)代理就是編譯的時(shí)候就已經(jīng)確定,而動(dòng)態(tài)代理就是運(yùn)行時(shí)才會(huì)生成 緩存代理 ● 提供數(shù)據(jù)的緩存功能,避免數(shù)據(jù)庫(kù)重復(fù)查詢(xún) 實(shí)踐 定義數(shù)據(jù)查詢(xún)的接口 接口實(shí)現(xiàn)類(lèi)實(shí)現(xiàn)接口

    2024年02月11日
    瀏覽(23)
  • 設(shè)計(jì)模式——代理模式

    代理模式(Proxy Pattern)是一種結(jié)構(gòu)型設(shè)計(jì)模式,它為其他對(duì)象提供一個(gè)代理以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。代理對(duì)象在客戶(hù)端和目標(biāo)對(duì)象之間起到中介作用,可以添加額外的功能或限制對(duì)目標(biāo)對(duì)象的直接訪問(wèn)。 抽象主題(Subject Interface): 定義了目標(biāo)對(duì)象和代理對(duì)象共有的接口。

    2024年01月17日
    瀏覽(21)
  • 設(shè)計(jì)模式二:代理模式

    設(shè)計(jì)模式二:代理模式

    1、什么是動(dòng)態(tài)代理 可能很多小伙伴首次接觸動(dòng)態(tài)代理這個(gè)名詞的時(shí)候,或者是在面試過(guò)程中被問(wèn)到動(dòng)態(tài)代理的時(shí)候,不能很好的描述出來(lái),動(dòng)態(tài)代理到底是個(gè)什么高大上的技術(shù)。不方,其實(shí)動(dòng)態(tài)代理的使用非常廣泛,例如我們平常使用的 Spring 中的 @Transactional 注解,其依賴(lài)

    2024年02月20日
    瀏覽(24)
  • 設(shè)計(jì)模式之代理模式

    當(dāng)我們有對(duì)象因?yàn)榘踩裕荒苤苯訉?duì)外暴露,或者是需要對(duì)對(duì)象的操作本身記錄日志等信息時(shí)就可以考慮使用代理模式, 享元設(shè)計(jì)模式,包含如下元素: UML圖如下: 另外,代理又分為靜態(tài)代理和動(dòng)態(tài)代理,靜態(tài)代理就是在編譯器已經(jīng)確定的代理方式,即是硬編碼到程序中

    2024年02月16日
    瀏覽(18)
  • 設(shè)計(jì)模式|代理模式

    設(shè)計(jì)模式|代理模式

    ?代理模式指為其他對(duì)象提供一種代理,以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。在某些情況下,一個(gè)對(duì)象若不能直接引用另一個(gè)對(duì)象,而代理對(duì)象可以在客戶(hù)端與目標(biāo)對(duì)象之間起到中介的作用。 普通代理 普通代理模式是指在代理模式中,代理對(duì)象和真實(shí)對(duì)象都實(shí)現(xiàn)了相同的接口或繼承

    2024年02月04日
    瀏覽(20)
  • 設(shè)計(jì)模式--代理模式

    設(shè)計(jì)模式--代理模式

    筆記來(lái)源:尚硅谷Java設(shè)計(jì)模式(圖解+框架源碼剖析) 1)代理模式:為一個(gè)對(duì)象提供一個(gè)替身,以控制對(duì)這個(gè)對(duì)象的訪問(wèn)。即 通過(guò)代理對(duì)象訪問(wèn)目標(biāo)對(duì)象 2)這樣做的好處是:可以在目標(biāo)對(duì)象實(shí)現(xiàn)的基礎(chǔ)上,增強(qiáng)額外的功能操作,即擴(kuò)展目標(biāo)對(duì)象的功能 3)被代理的對(duì)象可以

    2024年02月10日
    瀏覽(19)
  • 【設(shè)計(jì)模式】-代理模式

    在軟件開(kāi)發(fā)中,經(jīng)常遇到需要對(duì)某個(gè)對(duì)象進(jìn)行控制或者監(jiān)控的場(chǎng)景。而直接修改對(duì)象的代碼可能使代碼變得復(fù)雜且難以維護(hù)。這時(shí),使用代理模式(Proxy Pattern)可以很好地解決這個(gè)問(wèn)題。 ?????????代理模式是一種結(jié)構(gòu)型設(shè)計(jì)模式, 通過(guò)引入一個(gè)代理對(duì)象來(lái)替代原始對(duì)象

    2024年02月13日
    瀏覽(29)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包