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

[Java]靜態(tài)代理、動(dòng)態(tài)代理(基于JDK1.8)

這篇具有很好參考價(jià)值的文章主要介紹了[Java]靜態(tài)代理、動(dòng)態(tài)代理(基于JDK1.8)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

【版權(quán)聲明】未經(jīng)博主同意,謝絕轉(zhuǎn)載?。ㄕ?qǐng)尊重原創(chuàng),博主保留追究權(quán))
https://www.cnblogs.com/cnb-yuchen/p/18002823
出自【進(jìn)步*于辰的博客】

參考筆記一,P83;筆記二,P75.4。

目錄
  • 1、概述
  • 2、靜態(tài)代理的兩種形式
    • 2.1 面向接口
    • 2.2 面向繼承
  • 3、動(dòng)態(tài)代理的兩種形式
    • 3.1 JDK動(dòng)態(tài)代理
    • 3.2 Cglib動(dòng)態(tài)代理
  • 最后

1、概述

什么是代理模式?“代理模式”指通過為目標(biāo)對(duì)象(原代碼)創(chuàng)建代理對(duì)象,將附加功能(附加代碼)注入目標(biāo)對(duì)象的方法,從而實(shí)現(xiàn)附加功能的設(shè)計(jì)模式,分為靜態(tài)代理和動(dòng)態(tài)代理。

什么是靜態(tài)代理?“靜態(tài)代理”指為目標(biāo)類手動(dòng)創(chuàng)建代理類的代理方式。

什么是動(dòng)態(tài)代理?“動(dòng)態(tài)代理”指在不變動(dòng)原代碼的情況下,通過反射動(dòng)態(tài)創(chuàng)建代理對(duì)象的代理方式。(注:“反射”是動(dòng)態(tài)代理的底層,不可見)

2、靜態(tài)代理的兩種形式

2.1 面向接口

特點(diǎn):目標(biāo)對(duì)象與代理對(duì)象隸屬于同一接口。

看下述代碼:
1、公共接口:目標(biāo)類和代理類的公共接口。

interface IService {
    int transfer(int money);
}

2、目標(biāo)類。

class Target implements IService {
    @Override
    public int transfer(int money) {
        System.out.println("轉(zhuǎn)賬金額:" + money);
        return 1;
    }
}

3、代理類。

class Proxy implements IService {
    private Target target;
    public Proxy(Target target) {
        this.target = target;
    }

    @Override
    public int transfer(int score) {
        System.out.println("打開事務(wù)");// 附加功能
        int x = target.transfer(score);
        System.out.println("關(guān)閉事務(wù)");
        return x;
    }
}

測(cè)試。

class Test {
    public static void main(String[] args) {
        Proxy proxy = new Proxy(new Target());// 創(chuàng)建代理對(duì)象
        int x = proxy.transfer(10);
        if (x > 0)
            System.out.println("轉(zhuǎn)賬成功");
        else
            System.out.println("轉(zhuǎn)賬失敗");
    }
}

測(cè)試結(jié)果:
[Java]靜態(tài)代理、動(dòng)態(tài)代理(基于JDK1.8)

2.2 面向繼承

特點(diǎn):目標(biāo)對(duì)象與代理對(duì)象是繼承關(guān)系,代理對(duì)象繼承于目標(biāo)對(duì)象。

看下述代碼:
1、目標(biāo)類。

class Target {
    public int transfer(int money) {
        System.out.println("轉(zhuǎn)賬金額:" + money);
        return 1;
    }
}

3、代理類。

class Proxy extends Target {
    @Override
    public int transfer(int money) {
        System.out.println("打開事務(wù)");// 附加功能
        int x = super.transfer(money);
        System.out.println("關(guān)閉事務(wù)");
        return x;
    }
}

測(cè)試。

class Test {
    public static void main(String[] args) {
        Proxy proxy = new Proxy();// 創(chuàng)建代理對(duì)象
        int x = proxy.transfer(20);
        if (x > 0)
            System.out.println("轉(zhuǎn)賬成功");
        else
            System.out.println("轉(zhuǎn)賬失敗");
    }
}

測(cè)試結(jié)果:
[Java]靜態(tài)代理、動(dòng)態(tài)代理(基于JDK1.8)

3、動(dòng)態(tài)代理的兩種形式

PS:靜態(tài)代理需要手動(dòng)創(chuàng)建代理類,進(jìn)而創(chuàng)建代理對(duì)象,很冗余。換個(gè)思路,反射可以根據(jù) Class 信息創(chuàng)建實(shí)例,故可以通過反射為目標(biāo)對(duì)象創(chuàng)建代理對(duì)象,則無需創(chuàng)建代理類,這就是“動(dòng)態(tài)代理”。

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

特點(diǎn):面向接口,隸屬于Java API。

看下述代碼:
1、公共接口。

/**
 * 目標(biāo)對(duì)象與代理對(duì)象的公共接口
 * 注:因?yàn)镴DK動(dòng)態(tài)代理面向接口,故目標(biāo)對(duì)象和代理對(duì)象實(shí)現(xiàn)于同一接口
 */
interface IService {
    int transfer(int money);
}

2、目標(biāo)類。

class Target implements IService {
    @Override
    public int transfer(int money) {
        System.out.println("轉(zhuǎn)賬金額:" + money);
        return 1;
    }
}

測(cè)試。

class Test {
    public static void main(String[] args) {
        Target target = new Target();
        /**
         * 通過 newProxyInstance() 創(chuàng)建代理對(duì)象
         *     第一個(gè)參數(shù)是目標(biāo)對(duì)象的類加載器,指定為哪個(gè)目標(biāo)對(duì)象創(chuàng)建代理對(duì)象;
         *     第二個(gè)參數(shù)是目標(biāo)對(duì)象實(shí)現(xiàn)的接口,指定目標(biāo)對(duì)象和代理對(duì)象的公共接口;
         *     第三個(gè)參數(shù)是攔截器對(duì)象,指定用哪個(gè)攔截器來創(chuàng)建代理對(duì)象,需要實(shí)現(xiàn) InvocationHandler 接口。
         */
        // 由于代理對(duì)象 proxy 是通過反射創(chuàng)建于JVM,并無類存在,故要上轉(zhuǎn)為公共接口 IService
        IService proxyInstance = (IService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * 代理(調(diào)用 transfer())時(shí)執(zhí)行的方法
                     * @param proxy  代理對(duì)象,即 proxyInstance,暫不知如何使用
                     * @param method 目標(biāo)對(duì)象的 Method 的 class 對(duì)象
                     * @param args   目標(biāo)對(duì)象的 Method 的形參數(shù)組
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("打開事務(wù)");// 附加功能
                        // invoke() 是反射中 Method 對(duì)象執(zhí)行時(shí)調(diào)用的方法,故動(dòng)態(tài)代理是通過反射調(diào)用目標(biāo)對(duì)象被代理的方法
                        Object result = method.invoke(target, args);
                        System.out.println("關(guān)閉事務(wù)");
                        return result;
                    }
                });// 創(chuàng)建代理對(duì)象
        int x = proxyInstance.transfer(50);
        if (x > 0)
            System.out.println("轉(zhuǎn)賬成功");
        else
            System.out.println("轉(zhuǎn)賬失敗");
    }
}


測(cè)試結(jié)果:
[Java]靜態(tài)代理、動(dòng)態(tài)代理(基于JDK1.8)
可以用Lambda表達(dá)式進(jìn)行簡(jiǎn)化。

3.2 Cglib動(dòng)態(tài)代理

特點(diǎn):面向繼承,隸屬于Spring API。

看下述代碼:
1、目標(biāo)類。

class Target {
    public int transfer(int money) {
        System.out.println("轉(zhuǎn)賬金額:" + money);
        return 1;
    }
}

2、代理類。

/**
 * Cglib動(dòng)態(tài)代理類,需實(shí)現(xiàn)接口 MethodInterceptor
 */
class DynamicProxy implements MethodInterceptor {
    private Object target;
    public DynamicProxy(Object target) {
        this.target = target;
    }
    public Object createProxy() {
        Enhancer proxy = new Enhancer();// Enhancer 類是一種類生成器
        proxy.setCallback(this);// 設(shè)置攔截器,指定回對(duì)象為自身(暫不理解)
        proxy.setSuperclass(target.getClass());// 設(shè)置父類,指定為哪個(gè)目標(biāo)對(duì)象創(chuàng)建代理對(duì)象
        return proxy.create();// 創(chuàng)建代理對(duì)象
    }

    /**
     * 代理(調(diào)用 transfer())時(shí)執(zhí)行的方法
     * @param proxy       代理對(duì)象,即 proxyInstance,暫不知如何使用
     * @param method      目標(biāo)對(duì)象的 Method 的 class對(duì)象
     * @param args        目標(biāo)對(duì)象的 Method 的參數(shù)數(shù)組
     * @param methodProxy 代理方法,即 Target.transfer(),暫不知如何使用
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("打開事務(wù)");// 附加功能
        // invoke() 是反射中 Method 對(duì)象執(zhí)行時(shí)調(diào)用的方法,故動(dòng)態(tài)代理是通過反射調(diào)用目標(biāo)對(duì)象被代理的方法
        Object result = method.invoke(target, args);
        System.out.println("關(guān)閉事務(wù)");
        return result;
    }
}

測(cè)試。

class Test {
    public static void main(String[] args) {
        Target target = new Target();
        Target proxyInstance = (Target) new DynamicProxy(target).createProxy();
        int x = proxyInstance.transfer(100);
        if (x > 0)
            System.out.println("轉(zhuǎn)賬成功");
        else
            System.out.println("轉(zhuǎn)賬失敗");
    }
}


測(cè)試結(jié)果:
[Java]靜態(tài)代理、動(dòng)態(tài)代理(基于JDK1.8)

同樣可以用Lambda表達(dá)式進(jìn)行簡(jiǎn)化,不過代理對(duì)象的創(chuàng)建(proxy.create())需要對(duì) Enhancer 類的屬性進(jìn)行一些設(shè)置,故進(jìn)行了封裝。

注意:JDK動(dòng)態(tài)代理和Cglib動(dòng)態(tài)代理皆可攔截所有方法,包括:toString()、hashcode()。不能攔截由 final 修飾方法,如:getClass()。

最后

本文中的例子是為了闡述靜態(tài)代理和動(dòng)態(tài)代理的實(shí)現(xiàn)思想、方便大家理解而簡(jiǎn)單舉出的,不一定有實(shí)用性,大家自行擴(kuò)展。

本文完結(jié)。文章來源地址http://www.zghlxwxcb.cn/news/detail-837618.html

到了這里,關(guān)于[Java]靜態(tài)代理、動(dòng)態(tài)代理(基于JDK1.8)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(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)文章

  • 溫故知新之:代理模式,靜態(tài)代理和動(dòng)態(tài)代理(JDK動(dòng)態(tài)代理)

    溫故知新之:代理模式,靜態(tài)代理和動(dòng)態(tài)代理(JDK動(dòng)態(tài)代理)

    代理模式可以在不修改被代理對(duì)象的基礎(chǔ)上,通過擴(kuò)展代理類,進(jìn)行一些功能的附加與增強(qiáng)。 靜態(tài)代理 是一種代理模式的實(shí)現(xiàn)方式,它在編譯期間就已經(jīng)確定了代理對(duì)象,需要為每一個(gè)被代理對(duì)象創(chuàng)建一個(gè)代理類。靜態(tài)代理的實(shí)現(xiàn)比較簡(jiǎn)單,但是每個(gè)被代理對(duì)象都需要?jiǎng)?chuàng)建

    2024年02月11日
    瀏覽(30)
  • 靜態(tài)代理、jdk、cglib動(dòng)態(tài)代理 搞不清? 看這個(gè)文章就懂了

    靜態(tài)代理、jdk、cglib動(dòng)態(tài)代理 搞不清? 看這個(gè)文章就懂了

    代理模式是一種比較好的理解的設(shè)計(jì)模式。簡(jiǎn)單來說就是 : 我們使用代理對(duì)象來增強(qiáng)目標(biāo)對(duì)象(target obiect),這樣就可以在不修改原目標(biāo)對(duì)象的前提下,提供額外的功能操作,擴(kuò)展目標(biāo)對(duì)象的功能。 將核心業(yè)務(wù)代碼和非核心的公共代碼分離解耦,提高代碼可維護(hù)性,讓被代理

    2024年02月14日
    瀏覽(20)
  • MAC(適用于M1,M2芯片)下載Java8(官方 ARM64 JDK1.8)安裝、配置環(huán)境,支持動(dòng)態(tài)切換JDK

    MAC(適用于M1,M2芯片)下載Java8(官方 ARM64 JDK1.8)安裝、配置環(huán)境,支持動(dòng)態(tài)切換JDK

    官方下載地址 https://www.oracle.com/cn/java/technologies/downloads/ 這個(gè)是官方新發(fā)布的適配了M1、M2芯片的ARM64版本的jdk8,再也不用去第三方下載了,也不用滿世界的去找第三方j(luò)dk缺少的jar包了,而且更快更強(qiáng)!! 可以下載免安裝版, 這樣就可以配置多個(gè)版本的jdk了,配置如下 使配置

    2024年02月08日
    瀏覽(41)
  • Java代理模式——靜態(tài)代理與動(dòng)態(tài)代理

    Java代理模式——靜態(tài)代理與動(dòng)態(tài)代理

    代理模式允許你為其他對(duì)象提供一個(gè)代理,以控制對(duì)這個(gè)對(duì)象的訪問。代理模式在不改變實(shí)際對(duì)象的情況下,可以在訪問對(duì)象時(shí)添加額外的功能。 可以理解為代理模式為被代理對(duì)象創(chuàng)造了一個(gè)替身,調(diào)用者可以通過這個(gè)替身去實(shí)現(xiàn)這個(gè)被代理對(duì)象的功能,這個(gè)替身也可以為被

    2024年02月13日
    瀏覽(21)
  • Java——JDK動(dòng)態(tài)代理

    Java——JDK動(dòng)態(tài)代理

    動(dòng)態(tài)代理(理解) 基于反射機(jī)制 舉個(gè)例子,生活中一般在打官司的時(shí)候都會(huì)請(qǐng)代理律師,為什么要請(qǐng)律師呢?是因?yàn)殚_庭的時(shí)候大部人對(duì)于打官司沒有經(jīng)驗(yàn),只會(huì)說出自己案件的陳述,并不會(huì)根據(jù)法律等爭(zhēng)取自己權(quán)益的最大化,此時(shí)就可以請(qǐng)律師幫助自己不僅完成對(duì)案件的陳述

    2024年02月09日
    瀏覽(24)
  • Java中的代理模式(二)JDK動(dòng)態(tài)代理

    大家好??,我是極客濤??,上一篇中我們對(duì)代理模式有兩大類,靜態(tài)代理和動(dòng)態(tài)代理,對(duì)于靜態(tài)代理相信大家都信手拈來。對(duì)于動(dòng)態(tài)代理還有兩種實(shí)現(xiàn),一種是java原生的Jdk代理,一種是Cglib方式。因?yàn)樯婕暗皆创a解讀,所以我也將分兩期完成,本期主要講講JDK動(dòng)態(tài)代理的實(shí)

    2024年01月22日
    瀏覽(20)
  • Java代理之jdk動(dòng)態(tài)代理+應(yīng)用場(chǎng)景實(shí)戰(zhàn)

    Java代理之jdk動(dòng)態(tài)代理+應(yīng)用場(chǎng)景實(shí)戰(zhàn)

    本文將先介紹jdk動(dòng)態(tài)代理的基本用法,并對(duì)其原理和注意事項(xiàng)予以說明。之后將以兩個(gè)最常見的應(yīng)用場(chǎng)景為例,進(jìn)行代碼實(shí)操。這兩個(gè)應(yīng)用場(chǎng)景分別是 攔截器 和 聲明性接口 ,它們?cè)谠S多開發(fā)框架中廣泛使用。比如在spring和mybatis中均使用了攔截器模式,在mybatis中還利用動(dòng)態(tài)

    2023年04月10日
    瀏覽(24)
  • 【Java】JDK動(dòng)態(tài)代理實(shí)現(xiàn)原理

    【Java】JDK動(dòng)態(tài)代理實(shí)現(xiàn)原理

    代理模式 代理模式一般包含三個(gè)角色: Subject :主題對(duì)象,一般是一個(gè)接口,定義一些業(yè)務(wù)相關(guān)的基本方法。 RealSubject :具體的主題對(duì)象實(shí)現(xiàn)類,它會(huì)實(shí)現(xiàn)Subject接口中的方法。 Proxy :代理對(duì)象,里面包含一個(gè)RealSubject的引用,外部會(huì)通過這個(gè)代理對(duì)象,來實(shí)現(xiàn)RealSubject中方

    2024年02月08日
    瀏覽(22)
  • Java 代理模式詳解,靜態(tài)代理與動(dòng)態(tài)代理的區(qū)別及優(yōu)缺點(diǎn)

    代理模式是一種常用的設(shè)計(jì)模式,它允許通過引入一個(gè)代理對(duì)象來控制對(duì)目標(biāo)對(duì)象的訪問。在Java中,代理模式被廣泛應(yīng)用,它可以提供額外的功能,如權(quán)限檢查、緩存、日志記錄等,同時(shí)還能在不修改目標(biāo)對(duì)象的情況下對(duì)其進(jìn)行擴(kuò)展。 代理模式(Proxy Pattern)是指通過代理對(duì)象

    2024年02月11日
    瀏覽(27)
  • 【面試精講】Java動(dòng)態(tài)代理是如何實(shí)現(xiàn)的?JDK Proxy 和 CGLib 有什么區(qū)別?

    【面試精講】Java動(dòng)態(tài)代理是如何實(shí)現(xiàn)的?JDK Proxy 和 CGLib 有什么區(qū)別?

    Java動(dòng)態(tài)代理是如何實(shí)現(xiàn)的?JDK Proxy 和 CGLib 有什么區(qū)別? 一、Java動(dòng)態(tài)代理的實(shí)現(xiàn) 1、使用JDK Proxy實(shí)現(xiàn)動(dòng)態(tài)代理 2、使用CGLib實(shí)現(xiàn)動(dòng)態(tài)代理 二、JDK Proxy 與 CGLib 的區(qū)別 三、Spring中的動(dòng)態(tài)代理 四、?Lombok代理原理 總結(jié) 本文深入探討了Java動(dòng)態(tài)代理的實(shí)現(xiàn)機(jī)制,分別介紹了使用JDK

    2024年03月14日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包