0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

JDK動態(tài)代理的原理

科技綠洲 ? 來源:Java技術指北 ? 作者:Java技術指北 ? 2023-09-30 10:51 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Java中,動態(tài)代理是一種機制,允許在運行時動態(tài)地創(chuàng)建代理對象來代替某個實際對象,從而在其前后執(zhí)行額外的邏輯。

為什么JDK動態(tài)代理只能代理接口實現(xiàn)類,原因是JDK動態(tài)代理是基于接口實現(xiàn)的。

當你使用Proxy類創(chuàng)建代理對象時,你需要指定一個接口列表來表示代理對象所應該實現(xiàn)的接口,這些接口就成為代理對象的類型。

具體來說,代理對象的方法調用會被轉發(fā)到實現(xiàn)InvocationHandler接口的類中的invoke()方法。這個invoke()方法接受三個參數(shù):代理對象本身、被調用的方法對象和方法的參數(shù)數(shù)組。invoke()方法需要返回被代理方法調用的結果。

由于代理對象的類型是由接口列表決定的,因此只有實現(xiàn)了接口的類才能被代理。如果你想代理一個類而不是一個接口,你需要使用其他的代理技術,比如CGLIB。

1、JDK動態(tài)代理代碼實例

下面是一個簡單的示例代碼,展示了如何使用JDK動態(tài)代理來創(chuàng)建代理對象。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyDemo {
    public static void main(String[] args) {
        RealObject real = new RealObject();
        InvocationHandler handler = new DynamicProxy(real);

        // 創(chuàng)建代理對象
        MyInterface proxy = (MyInterface) Proxy.newProxyInstance(
                MyInterface.class.getClassLoader(),
                new Class< ? >[] { MyInterface.class },
                handler);

        // 調用代理對象的方法
        proxy.doSomething();
    }
}

interface MyInterface {
    void doSomething();
}

class RealObject implements MyInterface {
    public void doSomething() {
        System.out.println("RealObject doSomething");
    }
}

class DynamicProxy implements InvocationHandler {
    private Object target;

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

    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("Before method invocation");
        Object result = method.invoke(target, args);
        System.out.println("After method invocation");
        return result;
    }
}

在上面的代碼中,RealObject實現(xiàn)了MyInterface接口,它是我們要代理的實際對象。DynamicProxy類實現(xiàn)了InvocationHandler接口,并在invoke()方法中添加了額外的邏輯,用于在代理對象方法調用前后執(zhí)行。

main()方法中,我們使用Proxy.newProxyInstance()方法創(chuàng)建代理對象。我們指定了MyInterface接口作為代理對象類型,并將DynamicProxy對象作為代理對象的InvocationHandler

最后,我們調用代理對象的doSomething()方法,并觀察控制臺輸出的結果。

需要注意的是,代理對象的方法調用都會被轉發(fā)到DynamicProxy類的invoke()方法中進行處理,因此在這個示例中,實際的RealObject對象的doSomething()方法的執(zhí)行是在invoke()方法中通過反射進行的。

總結一下,JDK動態(tài)代理只能代理接口實現(xiàn)類,原因是JDK動態(tài)代理是基于接口實現(xiàn)的,代理對象的類型由接口列表決定。如果你想代理一個類而不是一個接口,你需要使用其他的代理技術,比如CGLIB。

2、Cglib 代碼演示

以下是CGLIB代理的示例代碼。

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CGLIBProxyDemo {
    public static void main(String[] args) {
        RealObject real = new RealObject();
        MethodInterceptor handler = new CGLIBProxy(real);

        // 創(chuàng)建代理對象
        RealObject proxy = (RealObject) Enhancer.create(
                RealObject.class,
                handler);

        // 調用代理對象的方法
        proxy.doSomething();
    }
}

class CGLIBProxy implements MethodInterceptor {
    private Object target;

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

    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before method invocation");
        Object result = proxy.invoke(target, args);
        System.out.println("After method invocation");
        return result;
    }
}

在上面的示例中,我們使用CGLIB的Enhancer類和MethodInterceptor接口來創(chuàng)建代理對象。RealObject類不再需要實現(xiàn)接口,而是直接作為代理對象的類型。在CGLIBProxy類中,我們實現(xiàn)了MethodInterceptor接口,并在intercept()方法中添加了額外的邏輯。

main()方法中,我們使用Enhancer.create()方法創(chuàng)建代理對象。我們指定了RealObject類作為代理對象類型,并將CGLIBProxy對象作為代理對象的MethodInterceptor。最后,我們調用代理對象的doSomething()方法,并觀察控制臺輸出的結果。

需要注意的是,CGLIB代理使用字節(jié)碼技術來生成代理對象,因此它的效率比JDK動態(tài)代理要高,但是它也需要額外的庫依賴。

3、兩者優(yōu)缺點

JDK動態(tài)代理和CGLIB代理都有它們自己的優(yōu)缺點。

JDK動態(tài)代理的優(yōu)點:

  • JDK動態(tài)代理是Java標準庫的一部分,因此它不需要引入任何外部依賴。
  • JDK動態(tài)代理只需要實現(xiàn)接口即可生成代理對象,不需要改變原有類的結構。
  • 由于JDK動態(tài)代理是基于接口實現(xiàn)的,因此它更適合用于代理接口實現(xiàn)類的場景。

JDK動態(tài)代理的缺點:

  • JDK動態(tài)代理只能代理實現(xiàn)了接口的類,無法代理沒有實現(xiàn)接口的類。
  • JDK動態(tài)代理在生成代理對象時,需要使用反射機制,因此它的效率相對較低。

CGLIB代理的優(yōu)點:

  • CGLIB代理是基于字節(jié)碼技術實現(xiàn)的,因此它的效率比JDK動態(tài)代理更高。
  • CGLIB代理可以代理沒有實現(xiàn)接口的類。

CGLIB代理的缺點:

  • CGLIB代理需要引入外部依賴。
  • CGLIB代理在生成代理對象時,需要改變原有類的結構,因此它可能會引起一些問題,例如無法代理final類或final方法等問題。

綜上所述,JDK動態(tài)代理適用于代理接口實現(xiàn)類的場景,而CGLIB代理適用于代理沒有實現(xiàn)接口的類的場景。如果你需要代理接口實現(xiàn)類,而且不想引入額外的依賴,那么JDK動態(tài)代理是一個不錯的選擇;如果你需要代理沒有實現(xiàn)接口的類,那么CGLIB代理可能更適合你的需求。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 接口
    +關注

    關注

    33

    文章

    8991

    瀏覽量

    153650
  • 代理
    +關注

    關注

    1

    文章

    44

    瀏覽量

    11340
  • 數(shù)組
    +關注

    關注

    1

    文章

    420

    瀏覽量

    26512
  • JDK
    JDK
    +關注

    關注

    0

    文章

    83

    瀏覽量

    16881
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    javaassit如何實現(xiàn)代對目標類的代理

    語言,更是一門面向切面的編程語言,正是這個特性,讓Java更加地靈活。 可能你寫過基于Spring AOP的代碼,其原理都是基于JDK動態(tài)代理或者CGLIB來實現(xiàn),其局限性在于我們只能以方法作為連接點,來實現(xiàn)基于方法執(zhí)行過程的
    的頭像 發(fā)表于 09-25 11:18 ?1177次閱讀
    javaassit如何實現(xiàn)代對目標類的<b class='flag-5'>代理</b>

    Java自學教程SSM框架全覆蓋day9_04-aop簡介-基于jdk動態(tài)代理

    JAVA
    電子學習
    發(fā)布于 :2023年01月08日 19:44:12

    JDK的安裝、環(huán)境配置及使用

    :Windows下,直接運行exe文件,安裝到一個目錄,例如將其安裝到C:\jdk1.5目錄下面。安裝后,其中l(wèi)ib目錄下面保存的是java庫文件,bin目錄是一些執(zhí)行文件和動態(tài)連接庫文件,demo目錄
    發(fā)表于 12-06 00:19

    java jdk6.0官方下載

    java jdk6.0下載如何件: java jdk6.0安裝步驟: 第一步 JDK1.6的安裝步驟 第一步雙擊安裝文件jdk-6u7-windows-i586-p.exe
    發(fā)表于 10-17 11:47 ?155次下載
    java <b class='flag-5'>jdk</b>6.0官方下載

    java的動態(tài)代理機制和作用

    的我們的功能,我們更需要學習的是其底層是怎么樣的一個原理,而AOP的原理就是java的動態(tài)代理機制,所以本篇隨筆就是對java的動態(tài)機制進行一個回顧。 在java的動態(tài)
    發(fā)表于 09-27 14:37 ?0次下載

    java動態(tài)代理分析

    定義:為其他對象提供一種代理以控制對這個對象的訪問。 動態(tài)代理使用 java動態(tài)代理機制以巧妙的方式實現(xiàn)了
    發(fā)表于 09-27 15:14 ?0次下載

    java的動態(tài)代理

    代理模式是常用的java設計模式,他的特征是代理類與委托類有同樣的接口,代理類主要負責為委托類預處理消息、過濾消息、把消息轉發(fā)給委托類,以及事后處理消息等。代理類與委托類之間通常會存在
    發(fā)表于 03-12 14:12 ?0次下載

    基于JDK和CGLB分別實現(xiàn)的動態(tài)代理

    本文檔內容介紹了基于JDK和CGLB分別實現(xiàn)的動態(tài)代理及源代碼
    發(fā)表于 03-12 14:56 ?0次下載

    什么是動態(tài)ip代理電腦軟件?

    動態(tài)IP代理計算機軟件是計算機瀏覽器和Web群集服務器之間的網(wǎng)絡服務器。如果使用動態(tài)IP代理計算機軟件訪問Internet,則計算機瀏覽器不會立即轉到Web網(wǎng)絡服務器來檢索網(wǎng)頁,而是僅
    發(fā)表于 01-14 18:06 ?1066次閱讀
    什么是<b class='flag-5'>動態(tài)</b>ip<b class='flag-5'>代理</b>電腦軟件?

    Python爬蟲:工作者常用的動態(tài)IP代理

    爬蟲工作者應該經(jīng)常要與代理ip工具打交道,根據(jù)不同的抓取網(wǎng)站,大家要調用不同類型的動態(tài)ip代理。
    的頭像 發(fā)表于 06-28 16:29 ?3571次閱讀

    淺談字節(jié)碼增強技術系列2-Asm與Cglib

    Spring AOP 的實現(xiàn)原理是基于動態(tài)織入的動態(tài)代理技術,而動態(tài)代理技術又分為 Java JDK
    的頭像 發(fā)表于 12-20 10:03 ?946次閱讀

    mybatis接口動態(tài)代理原理

    MyBatis是一款輕量級的Java持久化框架,它通過XML或注解配置的方式,將數(shù)據(jù)庫操作與SQL語句解耦,提供了一種簡單、靈活的數(shù)據(jù)訪問方式。在MyBatis中,使用動態(tài)代理技術來實現(xiàn)接口的代理
    的頭像 發(fā)表于 12-03 11:52 ?1249次閱讀

    weblogic修改jdk路徑

    WebLogic是一個流行的Java應用服務器,可以用于部署和管理企業(yè)級Java應用程序。在WebLogic的安裝和配置過程中,我們可能會遇到需要修改JDK(Java Development Kit
    的頭像 發(fā)表于 12-05 14:46 ?1781次閱讀

    如何配置jdk的環(huán)境變量

    配置JDK的環(huán)境變量是在操作系統(tǒng)中設置一些路徑,以便能夠在命令提示符或終端中全局運行Java開發(fā)工具。這樣,您可以在任何位置運行Java程序。 以下是一步一步的指南來配置JDK的環(huán)境變量。 第一步
    的頭像 發(fā)表于 12-06 15:07 ?1213次閱讀

    在實際開發(fā)中,動態(tài)代理技術都是如何應用的?

    動態(tài)代理技術因其靈活性和強大的功能,在軟件開發(fā)中被廣泛應用,特別是在需要在運行時動態(tài)地改變對象行為的場景中。
    的頭像 發(fā)表于 09-23 07:46 ?411次閱讀

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會員交流學習
    • 獲取您個性化的科技前沿技術信息
    • 參加活動獲取豐厚的禮品