成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:為什么JDK動態(tài)代理只能代理接口?

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

哈嘍,大家好,我是了不起。如題,這個問題應(yīng)該面試常考題,當你遇到這個問題時,如果你能回答出來JDK動態(tài)代理的原理,然后引申Cglib 動態(tài)代理,那么這個面試官一定會對你刮目相看。

圖片

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

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

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

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

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

        // 調(diào)用代理對象的方法
        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()方法中添加了額外的邏輯,用于在代理對象方法調(diào)用前后執(zhí)行。

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

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

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

總結(jié)一下,JDK動態(tài)代理只能代理接口實現(xiàn)類,原因是JDK動態(tài)代理是基于接口實現(xiàn)的,代理對象的類型由接口列表決定。如果你想代理一個類而不是一個接口,你需要使用其他的代理技術(shù),比如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);

        // 調(diào)用代理對象的方法
        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。最后,我們調(diào)用代理對象的doSomething()方法,并觀察控制臺輸出的結(jié)果。

需要注意的是,CGLIB代理使用字節(jié)碼技術(shù)來生成代理對象,因此它的效率比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)接口即可生成代理對象,不需要改變原有類的結(jié)構(gòu)。
  • 由于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é)碼技術(shù)實現(xiàn)的,因此它的效率比JDK動態(tài)代理更高。
  • CGLIB代理可以代理沒有實現(xiàn)接口的類。

CGLIB代理的缺點:

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

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

責(zé)任編輯:武曉燕 來源: Java技術(shù)指北
相關(guān)推薦

2020-12-29 05:34:00

動態(tài)代理

2021-12-08 06:53:29

面試動態(tài)代理

2022-02-22 22:44:46

接口源碼對象

2023-12-06 08:23:44

代理模式設(shè)計模式

2022-04-29 08:17:38

RPC遠程代理代理模式

2015-09-22 11:09:47

Java 8動態(tài)代理

2021-04-22 09:58:15

JDK代理動態(tài)

2022-07-06 13:48:24

RedisSentinel機制

2021-03-16 21:42:37

反向代理正向代理

2024-02-04 16:51:47

2023-12-06 09:10:28

JWT微服務(wù)

2020-10-24 15:50:54

Java值傳遞代碼

2021-02-19 10:02:57

HTTPSJava安全

2021-01-21 07:53:29

面試官Promis打印e

2021-11-05 07:47:56

代理模式對象

2022-09-01 10:40:29

SpringAOPJDK

2024-04-15 10:16:38

2021-12-20 10:30:33

forforEach前端

2011-04-06 11:41:25

Java動態(tài)代理

2023-12-20 14:35:37

Java虛擬線程
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 伊人久久大香线 | 亚洲美乳中文字幕 | 中文字幕在线视频免费观看 | 91视视频在线观看入口直接观看 | 成人免费网视频 | 91视频观看 | 亚洲欧美一区二区在线观看 | 成人精品国产 | 8x国产精品视频一区二区 | 一道本不卡视频 | 午夜视频一区 | 超碰地址| 久久久久久高潮国产精品视 | 日日干天天操 | 国产精品久久久久久久久久久久 | 99国产精品久久久久 | 国产精品久久久久久久久久久久久 | 91精品国产777在线观看 | 一区二区精品在线 | 欧美黑人国产人伦爽爽爽 | 91精品久久久久久久久 | 国产精品国产亚洲精品看不卡15 | 欧美日韩一二三区 | 久久国产精品色av免费观看 | 逼逼网| 亚洲www| www.47久久青青 | 黄色视频a级毛片 | 欧美精品在线看 | 人妖videosex高潮另类 | 欧美黄色网 | 中文字幕一区在线 | 精品乱码一区二区三四区 | 日日综合 | 97av视频在线 | 天天干国产 | 日韩国产精品一区二区三区 | 日韩看片 | 不卡一区二区在线观看 | 中文字幕在线不卡播放 | 久久亚洲国产 |