欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JDK動(dòng)態(tài)代理詳細(xì)解析

 更新時(shí)間:2023年11月27日 10:13:21   作者:一碼評(píng)川  
這篇文章主要介紹了JDK動(dòng)態(tài)代理詳細(xì)解析,在Java的動(dòng)態(tài)代理機(jī)制中,有兩個(gè)重要的類和接口,一個(gè)是InvoInvocationHandler(接口)、Proxy(類),這一個(gè)類和接口是我們動(dòng)態(tài)代理所必須用到的,需要的朋友可以參考下

一、說(shuō)明

在Java的動(dòng)態(tài)代理機(jī)制中,有兩個(gè)重要的類和接口,一個(gè)是InvoInvocationHandler(接口)、Proxy(類),這一個(gè)類和接口是我們動(dòng)態(tài)代理所必須用到的。

在這里插入圖片描述

優(yōu)點(diǎn):

  • 對(duì)于實(shí)現(xiàn)了接口的類,可以直接使用基于接口的動(dòng)態(tài)代理進(jìn)行代理,非常方便
  • 代理類和被代理類都必須實(shí)現(xiàn)同一個(gè)接口,能夠?qū)崿F(xiàn)對(duì)被代理對(duì)象的方法調(diào)用進(jìn)行統(tǒng)一管理。
  • 性能上:在老版的jdk,jdk代理生成的類速度快,通過(guò)反射調(diào)用慢,cglib是jdk代理速度的10倍左右,jdk在版本每次升級(jí)都會(huì)有很大的性能提升,cglib停滯不前,jdk7 8的動(dòng)態(tài)代理性能在1萬(wàn)次實(shí)驗(yàn)中比cglib要快20%左右
  • jdk動(dòng)態(tài)代理如果目標(biāo)類未實(shí)現(xiàn)接口則無(wú)法代理,cglib是通過(guò)繼承的方式來(lái)動(dòng)態(tài)代理,若目標(biāo)類被final關(guān)鍵字修飾,則無(wú)法使用cglib做動(dòng)態(tài)代理

缺點(diǎn):

  • 只能代理實(shí)現(xiàn)了接口的類,對(duì)于沒(méi)有實(shí)現(xiàn)接口的類無(wú)法使用此種方式進(jìn)行代理。
  • jdk動(dòng)態(tài)代理只提供實(shí)現(xiàn)接口的目標(biāo)類代理,不支持沒(méi)有實(shí)現(xiàn)接口的目標(biāo)類的代理。如果目標(biāo)類沒(méi)有實(shí)現(xiàn)接口,只能用cglib代理

二、主要類方法的說(shuō)明

InvocationHandler接口

每個(gè)動(dòng)態(tài)代理類都必須實(shí)現(xiàn)InvocationHandler接口,并且每個(gè)代理類的實(shí)例都關(guān)聯(lián)到了一個(gè)handler,當(dāng)我們通過(guò)代理對(duì)象調(diào)用一個(gè)方法的時(shí)候,這個(gè)方法的調(diào)用就會(huì)被轉(zhuǎn)發(fā)為由InvocationHandler接口的invoke方法來(lái)進(jìn)行調(diào)用。

InvocationHandler接口的invoke方法

  • Object invoke(Object proxy, Method method, Object[] args) throws Throwable
  • proxy:  - 指代我們所代理的那個(gè)真實(shí)對(duì)象
  • method: - 指代的是我們所要調(diào)用真實(shí)對(duì)象的某個(gè)方法的Method對(duì)象
  • args:  - 指代的是調(diào)用真實(shí)對(duì)象某個(gè)方法時(shí)接受的參數(shù)

**proxy存在的意義:**

1. 可以使用反射獲取代理對(duì)象的信息(也就是proxy.getClass().getName())。

2. 可以將代理對(duì)象返回以進(jìn)行連續(xù)調(diào)用,這就是proxy存在的目的,因?yàn)閠his并不是代理對(duì)象。

Proxy 類

Proxy類的作用就是用來(lái)動(dòng)態(tài)創(chuàng)建一個(gè)代理類對(duì)象的類,它提供了許多的方法,但是我們用的最多的就是newProxyInstance這個(gè)方法

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
  • loader:   一個(gè)ClassLoader對(duì)象,定義了由哪個(gè)ClassLoader對(duì)象來(lái)對(duì)生成的代理對(duì)象進(jìn)行加載
  • interfaces:  一個(gè)Interface對(duì)象的數(shù)組,表示的是我將要給我需要代理的對(duì)象提供一組什么接口,如果我提供了一組接口給它,那么這個(gè)代理對(duì)象就宣稱實(shí)現(xiàn)了該接口(多態(tài)),這樣我就能調(diào)用這組接口中的方法了
  • h:   一個(gè)InvocationHandler對(duì)象,表示的是當(dāng)我這個(gè)動(dòng)態(tài)代理對(duì)象在調(diào)用方法的時(shí)候,會(huì)關(guān)聯(lián)到哪一個(gè)InvocationHandler對(duì)象上

打印代理的類:

System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

三、關(guān)鍵步驟

創(chuàng)建InvocationHandler實(shí)現(xiàn)類

public class MapperProxy<T> implements InvocationHandler {
      private Class<T> proxyInterface;
    //這里可以維護(hù)一個(gè)緩存,存這個(gè)接口的方法抽象的對(duì)象
    MapperProxy(Class<T> proxyInterface){
        this.proxyInterface = proxyInterface;
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("執(zhí)行前...");
        Constructor constructor  = proxyInterface.getConstructor();
        Object o =  constructor.newInstance();
        method.invoke(o,args);
        System.out.println("執(zhí)行后");
        return null;
    }
}

通過(guò) Proxy.newProxyInstance() 創(chuàng)建代理實(shí)例

 Fly fly = (Fly) Proxy.newProxyInstance(MyFly.class.getClassLoader(),new Class[]{Fly.class, Fly.Fly2.class},new MapperProxy<>(MyFly.class));

在這里插入圖片描述

-  創(chuàng)建代理類-   Class<?> cl = getProxyClass0(loader, intfs);

-  獲取有參構(gòu)造器  Constructor<?> cons = cl.getConstructor(constructorParams);這里的參數(shù)就是InvocationHandler

-  通過(guò)構(gòu)造器創(chuàng)建代理實(shí)例-參數(shù)就是方法的第三個(gè)參數(shù)

分析生成的代理類

在這里插入圖片描述

在這里插入圖片描述

結(jié)論 

  • 代理類會(huì)繼承Proxy ,這里也就解釋了為什么通過(guò)JDK生成的代理無(wú)法代理非接口實(shí)現(xiàn)類了
  • 代理類實(shí)現(xiàn)了傳入的所有接口類型

調(diào)用代理類的doFly()

這里會(huì)調(diào)用 super.h.invoke(this, m3, (Object[])null);

super.h就是我們?cè)賱?chuàng)建代理對(duì)象是傳入的MapperProxy,所有這里會(huì)執(zhí)行MapperProxy.invoke方法(在這里我們就可動(dòng)態(tài)的對(duì)該執(zhí)行方法進(jìn)行增強(qiáng))

在這里插入圖片描述

到此這篇關(guān)于JDK動(dòng)態(tài)代理詳細(xì)解析的文章就介紹到這了,更多相關(guān)JDK動(dòng)態(tài)代理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • IDEA?中使用?Hudi的示例代碼

    IDEA?中使用?Hudi的示例代碼

    這篇文章主要介紹了IDEA?中使用?Hudi的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • maven創(chuàng)建spark項(xiàng)目的pom.xml文件配置demo

    maven創(chuàng)建spark項(xiàng)目的pom.xml文件配置demo

    這篇文章主要為大家介紹了maven創(chuàng)建spark項(xiàng)目的pom.xml文件配置demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • 兩天沒(méi)解決的問(wèn)題chatgpt用了5秒搞定隱藏bug

    兩天沒(méi)解決的問(wèn)題chatgpt用了5秒搞定隱藏bug

    這篇文章主要為大家描述了我用了兩天沒(méi)解決的問(wèn)題chatgpt用了5秒搞定的全程介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Java透明窗體的設(shè)置方法

    Java透明窗體的設(shè)置方法

    在本文中我們給大家整理了關(guān)于Java透明窗體的設(shè)置方法以及需要注意的地方,需要的朋友們學(xué)習(xí)參考下。
    2019-03-03
  • Spring Boot定時(shí)任務(wù)的使用實(shí)例代碼

    Spring Boot定時(shí)任務(wù)的使用實(shí)例代碼

    這篇文章主要介紹了Spring Boot定時(shí)任務(wù)的使用實(shí)例代碼,需要的朋友可以參考下
    2017-04-04
  • Java運(yùn)行時(shí)動(dòng)態(tài)生成類實(shí)現(xiàn)過(guò)程詳解

    Java運(yùn)行時(shí)動(dòng)態(tài)生成類實(shí)現(xiàn)過(guò)程詳解

    這篇文章主要介紹了Java運(yùn)行時(shí)動(dòng)態(tài)生成類實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • idea 有時(shí)提示找不到類或者符號(hào)的解決

    idea 有時(shí)提示找不到類或者符號(hào)的解決

    這篇文章主要介紹了idea 有時(shí)提示找不到類或者符號(hào)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • Java數(shù)據(jù)結(jié)構(gòu)之鏈表詳解

    Java數(shù)據(jù)結(jié)構(gòu)之鏈表詳解

    本篇文章我們將講解一種新型的數(shù)據(jù)結(jié)構(gòu)—鏈表,鏈表是一種使用廣泛的通用數(shù)據(jù)結(jié)構(gòu),它可以用來(lái)作為實(shí)現(xiàn)棧,隊(duì)列等數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ).文中有非常詳細(xì)的介紹,需要的朋友可以參考下
    2021-05-05
  • Java數(shù)組聲明、創(chuàng)建、初始化基礎(chǔ)

    Java數(shù)組聲明、創(chuàng)建、初始化基礎(chǔ)

    本文講述了Java數(shù)組的幾個(gè)相關(guān)的方面,講述了對(duì)Java數(shù)組的聲明、創(chuàng)建和初始化,并給出其對(duì)應(yīng)的代碼
    2012-12-12
  • 基于springboot處理date參數(shù)過(guò)程解析

    基于springboot處理date參數(shù)過(guò)程解析

    這篇文章主要介紹了基于springboot處理date參數(shù)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12

最新評(píng)論