中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java動態代理實例分析

發布時間:2022-07-26 17:02:24 來源:億速云 閱讀:119 作者:iii 欄目:編程語言

這篇文章主要介紹“Java動態代理實例分析”,在日常操作中,相信很多人在Java動態代理實例分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java動態代理實例分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

Java動態代理實例分析

"代理"這個詞相信大家并不陌生,簡單來說就是代替廠家來售賣商品,代理替代廠家售賣商品,顧客找代理購買商品。也就是說:1)顧客和廠家之間是不可見的,顧客不知道背后的廠家是誰。2)代理可以對顧客進行“定位”,更精確的售賣給需要的客戶群體。

代理模式

代理模式:為其他對象提供一種代理以控制對這個對象的訪問,也就是創建一個代理對象作為客戶端和目標對象之間的中介,主要目的就是保護目標對象或增強目標對象

通過使用代理模式,通常有以下兩個優點:

\1) 可以隱藏被代理類的實現

\2) 可以實現客戶與被代理類間的解耦,在不修改被代理類代碼的情況下能夠做一些額外的處理

靜態代理

所謂的動態代理,就是通過聲明一個明確的代理類來訪問源對象,一個代理只能服務于一種產品,當有n種產品時,就需要n個代理,這樣就不利于業務的發展。

舉例:我們有兩個接口,Mouse和Keyboard,每個接口都有一個實現類

Java動態代理實例分析

Java動態代理實例分析

實現類中的代碼如下:

public class LogitechMouse implements Mouse{
    @Override
    public void sell() {
        System.out.println("出售羅技鼠標");
    }
}
public class HHKBKeyboard implements Keyboard{
    @Override
    public void sell() {
        System.out.println("出售HHKB鍵盤");
    }
}

現在我們要做的就是讓代理在調用sell()前輸出一句售前了解,調用后輸出一句售后服務

那我們只需寫兩個代理類MouseProxyKeyboardProxy

public class MouseProxy implements Mouse {
    private Mouse mouse;

    public MouseProxy(Mouse mouse) {
        this.mouse = mouse;
    }
    @Override
    public void sell() {
        System.out.println("售前了解");
        mouse.sell();
        System.out.println("售后服務");
    }
}
public class KeyboardProxy implements Keyboard{
    private Keyboard keyboard;
    public KeyboardProxy(Keyboard keyboard) {
        this.keyboard = keyboard;
    }
    @Override
    public void sell() {
        System.out.println("售前了解");
        keyboard.sell();
        System.out.println("售后服務");
    }
}

最終執行為:

public class Test {
    public static void main(String[] args) {
        Mouse logitechMouse = new LogitechMouse();
        MouseProxy mouseProxy = new MouseProxy(logitechMouse);
        mouseProxy.sell();
        Keyboard hhkbKeyboard = new HHKBKeyboard();
        KeyboardProxy keyboardProxy = new KeyboardProxy(hhkbKeyboard);
        keyboardProxy.sell();
    }
}

輸出:
售前了解
出售羅技鼠標
售后服務
售前了解
出售HHKB鍵盤
售后服務

靜態代理的代碼非常簡單易懂,這種模式雖好,但是也有明顯的缺點:

  • 會存在大量冗余的代理類,這里只有兩個接口,如果有n個接口,那么就要定義n個代理類。

  • 不易維護,一旦接口更改,代理類和被代理類都要更改。

那么這個時候就可以使用動態代理來解決了

動態代理

代理類在程序運行時創建代理的方式叫動態代理,也就是說代理類并不是在java代碼中定義的,而是在運行的時候動態生成的

JDK動態代理

JDK從1.3版本就開始支持動態代理類的創建。主要核心類只有2個:java.lang.reflect.Proxyjava.lang.reflect.InvocationHandler

還是上面的例子,用JDK動態代理如下:

public class JDKProxy implements InvocationHandler {
    private Object object;
    public JDKProxy(Object object) {
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("售前了解");
        Object invoke = method.invoke(object, args);
        System.out.println("售后服務");
        return invoke;
    }
}

當我們調用代理類對象的方法時,這個“調用”會轉送到invoke方法中,

代理類對象作為proxy參數傳入,

參數method標識了我們具體調用的是代理類的哪個方法,

args為這個方法的參數。

這樣一來,我們對代理類中的所有方法的調用都會變為對invoke的調用,這樣我們可以在invoke方法中添加統一的處理邏輯(也可以根據method參數對不同的代理類方法做不同的處理)。因此我們可以在中介類的invoke方法中實現輸出售前了解,再調用被代理類的方法,再輸出售后服務。

Java動態代理實例分析

執行代碼

public class Test {
    public static void main(String[] args) {
        Mouse logitechMouse = new LogitechMouse();
        JDKProxy jdkProxy = new JDKProxy(logitechMouse);
        Mouse mouse= (Mouse)Proxy.newProxyInstance(jdkProxy.getClass().getClassLoader(), new Class[]{Mouse.class}, jdkProxy);
        mouse.sell();
        HHKBKeyboard hhkbKeyboard = new HHKBKeyboard();
        JDKProxy jdkProxy1 = new JDKProxy(hhkbKeyboard);
        Keyboard keyboard = (Keyboard)Proxy.newProxyInstance(jdkProxy1.getClass().getClassLoader(), new Class[]{Keyboard.class}, jdkProxy1);
        keyboard.sell();
    }
}

可以看到無論多少個接口,只需要一個代理類就可以了。

CGLIB動態代理

代理類:

public class CGLIBProcy implements MethodInterceptor {
    private Enhancer enhancer = new Enhancer();
    private Object object;
    public CGLIBProcy(Object object) {
        this.object = object;
    }
    public Object getProxy(){
        //設置需要創建子類的類
        enhancer.setSuperclass(object.getClass());
        enhancer.setCallback(this);
        //創建代理對象
        return enhancer.create();
    }
    // o: cglib 動態生成的代理類的實例
    // method:實體類所調用的都被代理的方法的引用
    // objects 參數列表
    // methodProxy:生成的代理類對方法的代理引用
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("售前了解");
        Object invoke = method.invoke(object, objects);
        System.out.println("售后處理");
        return invoke;
    }
}

執行代碼:

public class Test {
    public static void main(String[] args) {
        Mouse logitechMouse = new LogitechMouse();
        CGLIBProcy cglibProcy = new CGLIBProcy(logitechMouse);
        Mouse proxy = (Mouse)cglibProcy.getProxy();
        proxy.sell();
        cglibProcy = new CGLIBProcy(new HHKBKeyboard());
        Keyboard keyboard = (Keyboard)cglibProcy.getProxy();
        keyboard.sell();
    }
}

JDK代理與CGLIB代理的區別

  • JDK動態代理實現接口,CGLIB動態繼承思想

  • JDK動態代理(目標對象存在接口時)執行效率高于CIGLIB

  • 如果對象有接口實現,選擇JDK代理,如果沒有接口實現選擇CGILB代理

到此,關于“Java動態代理實例分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

澄迈县| 白银市| 长葛市| 南投市| 通道| 仲巴县| 高要市| 剑阁县| 清新县| 塔河县| 贵南县| 临清市| 开鲁县| 南雄市| 平乡县| 阳新县| 措勤县| 二手房| 江阴市| 洪雅县| 旺苍县| 防城港市| 德格县| 米脂县| 绿春县| 综艺| 哈巴河县| 湖口县| 庐江县| 上饶市| 乌拉特后旗| 榆树市| 精河县| 小金县| 泉州市| 双鸭山市| 淮安市| 家居| 抚顺市| 永仁县| 竹山县|