亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java的動(dòng)態(tài)代理模式之Cglib代理詳解

 更新時(shí)間:2023年11月28日 08:33:59   作者:四葉草  
這篇文章主要介紹了Java的動(dòng)態(tài)代理模式之Cglib代理詳解,Cglib代理也叫作?子類(lèi)代理,它是在內(nèi)存中構(gòu)建一個(gè)子類(lèi)對(duì)象從而實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象功能擴(kuò)展,?有些書(shū)也將Cglib代理歸屬到動(dòng)態(tài)代理,需要的朋友可以參考下

1.Cglib 代理模式的基本介紹

  1. 靜態(tài)代理和 JDK 代理模式都要求目標(biāo)對(duì)象是實(shí)現(xiàn)一個(gè)接口,但是有時(shí)候目標(biāo)對(duì)象只是一個(gè) 單獨(dú)的對(duì)象,并沒(méi) 有實(shí)現(xiàn)任何的接口,這個(gè)時(shí)候可使用目標(biāo)對(duì)象子類(lèi)來(lái)實(shí)現(xiàn)代理-這就是 Cglib 代理
  2. Cglib代理也叫作 子類(lèi)代理,它是在內(nèi)存中構(gòu)建一個(gè)子類(lèi)對(duì)象從而實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象功能擴(kuò)展, 有些書(shū)也將Cglib代理歸屬到動(dòng)態(tài)代理。
  3. Cglib 是一個(gè)強(qiáng)大的高性能的代碼生成包,它可以在運(yùn)行期擴(kuò)展 java 類(lèi)與實(shí)現(xiàn) java 接口.它廣泛的被許多 AOP 的框架使用,例如 SpringAOP,實(shí)現(xiàn)方法攔截
  4. 在 AOP 編程中如何選擇代理模式:

目標(biāo)對(duì)象需要實(shí)現(xiàn)接口,用 JDK 代理

目標(biāo)對(duì)象不需要實(shí)現(xiàn)接口,用 Cglib 代理

Cglib 包的底層是通過(guò)使用字節(jié)碼處理框架 ASM 來(lái)轉(zhuǎn)換字節(jié)碼并生成新的類(lèi)

2.Cglib 代理模式實(shí)現(xiàn)步驟

需要引入 cglib 的 jar 文件

/*
cglib包結(jié)構(gòu):
net.sf.cglib.core    	底層字節(jié)碼處理類(lèi)。
net.sf.cglib.transform  該包中的類(lèi)用于class文件運(yùn)行時(shí)轉(zhuǎn)換或編譯時(shí)轉(zhuǎn)換。
net.sf.cglib.proxy    	該包中的類(lèi)用于創(chuàng)建代理和方法攔截。
net.sf.cglib.reflect    該包中的類(lèi)用于快速反射,并提供了C#風(fēng)格的委托。
net.sf.cglib.util    	集合排序工具類(lèi)。
net.sf.cglib.beans    	JavaBean工具類(lèi)。
*/

在內(nèi)存中動(dòng)態(tài)構(gòu)建子類(lèi),注意代理的類(lèi)不能為 final,否則報(bào)錯(cuò)java.lang.IllegalArgumentException:

目標(biāo)對(duì)象的方法如果為 final/static,那么就不會(huì)被攔截,即不會(huì)執(zhí)行目標(biāo)對(duì)象額外的業(yè)務(wù)方法.

3.cglib動(dòng)態(tài)代理相關(guān)的基礎(chǔ)類(lèi)

net.sf.cglib.proxy.Enhancer 主要的增強(qiáng)類(lèi)。

net.sf.cglib.proxy.MethodInterceptor 主要的方法攔截類(lèi),它是Callback接口的子接口,需要用戶實(shí)現(xiàn)。

net.sf.cglib.proxy.MethodProxy JDK的java.lang.reflect.Method類(lèi)的代理類(lèi),可以方便的實(shí)現(xiàn)對(duì)源對(duì)象方法的調(diào)用。

cglib是通過(guò)動(dòng)態(tài)的生成一個(gè)子類(lèi)去覆蓋所要代理類(lèi)的非final方法,并設(shè)置好callback,則原有類(lèi)的每個(gè)方法調(diào)用就會(huì)轉(zhuǎn)變成調(diào)用用戶定義的攔截方法(intercept)

4.Cglib 代理模式應(yīng)用實(shí)例

4.1 導(dǎo)入pom.xml依賴(lài)

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.1</version>
</dependency>

4.2 目標(biāo)類(lèi)

//火車(chē)站
public class TrainStation {

    public void sell() {
        System.out.println("火車(chē)站賣(mài)票");
    }
}

4.3 代理工廠

//代理工廠
public class ProxyFactory implements MethodInterceptor {

    //聲明目標(biāo)對(duì)象
    private TrainStation target = new TrainStation();

    public TrainStation getProxyObject() {
        //創(chuàng)建Enhancer對(duì)象,類(lèi)似于JDK動(dòng)態(tài)代理的Proxy類(lèi),下一步就是設(shè)置幾個(gè)參數(shù)
        Enhancer enhancer =new Enhancer();

        //設(shè)置代理對(duì)象的父類(lèi)的字節(jié)碼對(duì)象(Class類(lèi)型的對(duì)象) , 指定代理對(duì)象的父類(lèi)
        enhancer.setSuperclass(target.getClass());

        //設(shè)置回調(diào)函數(shù) , 實(shí)現(xiàn)調(diào)用代理對(duì)象的方法時(shí)最終都會(huì)執(zhí)行MethodInterceptor的子實(shí)現(xiàn)類(lèi)的intercept方法 , 在這個(gè)函數(shù)中利用反射完成任意目標(biāo)類(lèi)方法的調(diào)用
        enhancer.setCallback(this);

        //設(shè)置完參數(shù)后就可以 ,默認(rèn)返回的是Object類(lèi)型 , 可以進(jìn)行強(qiáng)轉(zhuǎn) , 創(chuàng)建真正的代理對(duì)象
        TrainStation obj = (TrainStation) enhancer.create();
        return obj;
    }
    // intercept方法參數(shù)說(shuō)明:
    //		返回值類(lèi)型是調(diào)用方法的返回值類(lèi)型
	//		o : 代理對(duì)象
	//		method : 真實(shí)對(duì)象中的方法的Method實(shí)例對(duì)象
	//		args : 實(shí)際參數(shù) , 可以是0到N個(gè)
	//		methodProxy :代理對(duì)象中的方法的method實(shí)例

    public TrainStation intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("代理點(diǎn)收取一些服務(wù)費(fèi)用(CGLIB動(dòng)態(tài)代理方式)");
        //調(diào)用目標(biāo)對(duì)象的方法
        TrainStation result = (TrainStation) methodProxy.invokeSuper(o, args);
        return result;
    }
}

Enhancer類(lèi)的常用方法

方法名功能
public Enhancer() , 無(wú)參構(gòu)造創(chuàng)建Enhancer對(duì)象,類(lèi)似于JDK動(dòng)態(tài)代理的Proxy類(lèi),并不是真正的代理對(duì)象 , 還沒(méi)有設(shè)置參數(shù)
setSuperclass()設(shè)置代理對(duì)象的父類(lèi)的字節(jié)碼對(duì)象(Class類(lèi)型的對(duì)象) , 指定代理對(duì)象的父類(lèi) , 參數(shù)一般寫(xiě)目標(biāo)類(lèi)的Class對(duì)象
setCallback()設(shè)置執(zhí)行哪個(gè)對(duì)象的回調(diào)函數(shù) , 調(diào)用代理對(duì)象的方法時(shí)最終都會(huì)執(zhí)行MethodInterceptor接口的子實(shí)現(xiàn)類(lèi)對(duì)象的intercept方法 , 在intercept方法中利用反射完成任意目標(biāo)類(lèi)方法的調(diào)用 一般讓代理工廠實(shí)現(xiàn)MethodInterceptor接口 , 那么方法參數(shù)就可以寫(xiě)this,這時(shí)MethodInterceptor接口的子實(shí)現(xiàn)類(lèi)對(duì)象就是代理工廠對(duì)象
public Object create()創(chuàng)建真正的代理對(duì)象 , 默認(rèn)返回的是Object類(lèi)型 , 可以強(qiáng)轉(zhuǎn)為目標(biāo)對(duì)象類(lèi)型 , 創(chuàng)建真正的代理對(duì)象

4.4 測(cè)試類(lèi)

//測(cè)試類(lèi)
public class Client {
    public static void main(String[] args) {
        //創(chuàng)建代理工廠對(duì)象
        ProxyFactory factory = new ProxyFactory();
        
        //獲取代理對(duì)象
        TrainStation proxyObject = factory.getProxyObject();

        proxyObject.sell();
    }
}

5 jdk代理和CGLIB代理

  • 使用CGLib實(shí)現(xiàn)動(dòng)態(tài)代理,CGLib底層采用ASM字節(jié)碼生成框架,使用字節(jié)碼技術(shù)生成代理類(lèi),在JDK1.6之前比使用Java反射效率要高。
  • 唯一需要注意的是,CGLib不能對(duì)聲明為final的類(lèi)或者方法進(jìn)行代理,因?yàn)镃GLib原理是動(dòng)態(tài)生成被代理類(lèi)的子類(lèi)。final修飾類(lèi)不能被繼承 , final修飾的方法不能被重寫(xiě)
  • 在JDK1.6、JDK1.7、JDK1.8逐步對(duì)JDK動(dòng)態(tài)代理優(yōu)化之后,在調(diào)用次數(shù)較少的情況下,JDK代理效率高于CGLib代理效率,只有當(dāng)進(jìn)行大量調(diào)用的時(shí)候,JDK1.6和JDK1.7比CGLib代理效率低一點(diǎn),但是到JDK1.8的時(shí)候,JDK代理效率高于CGLib代理。所以如果有接口使用JDK動(dòng)態(tài)代理,如果沒(méi)有接口使用CGLIB代理。

6 代理模式優(yōu)缺點(diǎn)及使用場(chǎng)景

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

  • 代理模式在客戶端與目標(biāo)對(duì)象之間起到一個(gè)中介作用和保護(hù)目標(biāo)對(duì)象的作用;
  • 代理對(duì)象可以擴(kuò)展目標(biāo)對(duì)象的功能;
  • 代理模式能將客戶端與目標(biāo)對(duì)象分離,在一定程度上降低了系統(tǒng)的耦合度;

缺點(diǎn):

  • 增加了系統(tǒng)的復(fù)雜度;

使用場(chǎng)景:

  • 遠(yuǎn)程(Remote)代理
    • 本地服務(wù)通過(guò)網(wǎng)絡(luò)請(qǐng)求遠(yuǎn)程服務(wù)。為了實(shí)現(xiàn)本地到遠(yuǎn)程的通信,我們需要實(shí)現(xiàn)網(wǎng)絡(luò)通信,處理其中可能的異常。為良好的代碼設(shè)計(jì)和可維護(hù)性,我們將網(wǎng)絡(luò)通信部分隱藏起來(lái),只暴露給本地服務(wù)一個(gè)接口,通過(guò)該接口即可訪問(wèn)遠(yuǎn)程服務(wù)提供的功能,而不必過(guò)多關(guān)心通信部分的細(xì)節(jié)。RPC思想
  • 防火墻(Firewall)代理
    • 當(dāng)你將瀏覽器配置成使用代理功能時(shí),防火墻就將你的瀏覽器的請(qǐng)求轉(zhuǎn)給互聯(lián)網(wǎng);當(dāng)互聯(lián)網(wǎng)返回響應(yīng)時(shí),代理服務(wù)器再把它轉(zhuǎn)給你的瀏覽器。
  • 保護(hù)(Protect or Access)代理
    • 務(wù)一個(gè)接口,通過(guò)該接口即可訪問(wèn)遠(yuǎn)程服務(wù)提供的功能,而不必過(guò)多關(guān)心通信部分的細(xì)節(jié)。RPC思想
  • 防火墻(Firewall)代理
    • 當(dāng)你將瀏覽器配置成使用代理功能時(shí),防火墻就將你的瀏覽器的請(qǐng)求轉(zhuǎn)給互聯(lián)網(wǎng);當(dāng)互聯(lián)網(wǎng)返回響應(yīng)時(shí),代理服務(wù)器再把它轉(zhuǎn)給你的瀏覽器。
  • 保護(hù)(Protect or Access)代理
    • 控制對(duì)一個(gè)對(duì)象的訪問(wèn),如果需要,可以給不同的用戶提供不同級(jí)別的使用權(quán)限。

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

相關(guān)文章

  • Spring 依賴(lài)注入實(shí)現(xiàn)示例

    Spring 依賴(lài)注入實(shí)現(xiàn)示例

    這篇文章主要介紹了Spring 依賴(lài)注入實(shí)現(xiàn)示例的相關(guān)資料,幫助大家更好的理解和使用spring框架,感興趣的朋友可以了解下
    2020-11-11
  • 老生常談 MyBatis 復(fù)雜查詢

    老生常談 MyBatis 復(fù)雜查詢

    這篇文章主要介紹了 MyBatis 復(fù)雜查詢的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Java實(shí)現(xiàn)雪花算法的原理和實(shí)戰(zhàn)教程

    Java實(shí)現(xiàn)雪花算法的原理和實(shí)戰(zhàn)教程

    這篇文章主要介紹了Java實(shí)現(xiàn)雪花算法的原理和實(shí)戰(zhàn)教程,本文通過(guò)語(yǔ)言表述和代碼的實(shí)現(xiàn)講解了該項(xiàng)算法,,需要的朋友可以參考下
    2021-06-06
  • 一文詳解SpringBoot?Redis多數(shù)據(jù)源配置

    一文詳解SpringBoot?Redis多數(shù)據(jù)源配置

    Spring?Boot默認(rèn)只允許一種?Redis?連接池配置,且配置受限于?Lettuce?包,不夠靈活,所以本文將為大家介紹如何自定義Redis配置方案實(shí)現(xiàn)多數(shù)據(jù)源支持,需要的可以參考下
    2024-11-11
  • java往php傳數(shù)據(jù)操作方法

    java往php傳數(shù)據(jù)操作方法

    在本篇內(nèi)容里小編給大家分享的是關(guān)于java往php傳數(shù)據(jù)操作方法和技巧,需要的朋友們可以跟著學(xué)習(xí)下。
    2018-12-12
  • Flink部署集群整體架構(gòu)源碼分析

    Flink部署集群整體架構(gòu)源碼分析

    這篇文章主要為大家介紹了Flink部署集群及整體架構(gòu)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • 解決MyEclipse出現(xiàn)the user operation is waiting的問(wèn)題

    解決MyEclipse出現(xiàn)the user operation is waiting的問(wèn)題

    今天做項(xiàng)目的時(shí)候每次修改代碼保存后都會(huì)跳出一個(gè)框框,然后就有兩個(gè)進(jìn)度條,上面寫(xiě)the user operation is wating...小編去網(wǎng)上查了查解決了這個(gè)問(wèn)題,下面跟大家分享一下。
    2018-04-04
  • Java JDBC批量執(zhí)行executeBatch方法詳解

    Java JDBC批量執(zhí)行executeBatch方法詳解

    這篇文章主要介紹了Java JDBC批量執(zhí)行executeBatch方法詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • java 使用poi動(dòng)態(tài)導(dǎo)出的操作

    java 使用poi動(dòng)態(tài)導(dǎo)出的操作

    這篇文章主要介紹了java 使用poi動(dòng)態(tài)導(dǎo)出的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • SpringBoot4.5.2 整合HikariCP 數(shù)據(jù)庫(kù)連接池操作

    SpringBoot4.5.2 整合HikariCP 數(shù)據(jù)庫(kù)連接池操作

    這篇文章主要介紹了SpringBoot4.5.2 整合HikariCP 數(shù)據(jù)庫(kù)連接池操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評(píng)論