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

Java JDK與cglib動(dòng)態(tài)代理有什么區(qū)別

 更新時(shí)間:2023年03月20日 09:31:26   作者:王佑輝  
這篇文章主要介紹了Java JDK動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理的區(qū)別文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧

一、說(shuō)明

1.spring aop中的動(dòng)態(tài)代理主要有兩種方式,jdk動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理

2.從實(shí)現(xiàn)接口、繼承父類的角度討論區(qū)別

3.從限制角度討論區(qū)別

4.從性能上討論區(qū)別

二、區(qū)別

1.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代理

2.jdk動(dòng)態(tài)代理會(huì)在運(yùn)行時(shí)為目標(biāo)類生成一個(gè)動(dòng)態(tài)代理類$proxy*.class。cglib的底層是通過(guò)ASM在運(yùn)行時(shí)動(dòng)態(tài)生成目標(biāo)類的子類,還會(huì)有其它類

3. jdk動(dòng)態(tài)代理的代理類實(shí)現(xiàn)了目標(biāo)類實(shí)現(xiàn)的接口,并且會(huì)實(shí)現(xiàn)接口所有方法來(lái)代碼增強(qiáng)。cglib動(dòng)態(tài)代理會(huì)重寫(xiě)父類所有的方法來(lái)代碼增強(qiáng)

4.jdk動(dòng)態(tài)代理調(diào)用時(shí)先去調(diào)用處理類進(jìn)行增強(qiáng),再通過(guò)反射的方式調(diào)用目標(biāo)類的方法。cglib動(dòng)態(tài)代理調(diào)用時(shí)先通過(guò)代理類進(jìn)行增強(qiáng),再直接調(diào)用父類對(duì)應(yīng)的方法進(jìn)行調(diào)用目標(biāo)方法

5.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)代理

6.性能上:在老版的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%左右

三、代碼示例

3.1 靜態(tài)代理

package com.proxy.staticproxy;
public interface SellTicket {
    void sell();
}
package com.proxy.staticproxy;
public class TrainStation implements SellTicket{
     @Override
     public void sell() {
         System.out.println("火車站售票");
     }
 }
package com.proxy.staticproxy;
public class ProxyPoint implements SellTicket{
    //聲明火車類對(duì)象
    private TrainStation trainStation = new TrainStation();
    @Override
    public void sell() {
        System.out.println("代售點(diǎn)收取服務(wù)費(fèi)");
        trainStation.sell();
    }
    public static void main(String[] args) {
        ProxyPoint proxyPoint = new ProxyPoint();
        proxyPoint.sell();
    }
}

3.2 jdk動(dòng)態(tài)代理

package com.proxy.jdkproxy;
import com.proxy.staticproxy.SellTicket;
import com.proxy.staticproxy.TrainStation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
    private TrainStation trainStation = new TrainStation();
    public SellTicket getProxyPoint() {
        /**
         * ClassLoader loader: 類加載器,用于加載代理類??梢酝ㄟ^(guò)目標(biāo)對(duì)象獲取類加載器
         * Class<?>[] interfaces: 代理類實(shí)現(xiàn)的接口的字節(jié)碼對(duì)象
         * InvocationHandler h: 代理對(duì)象的調(diào)用處理程序
         */
        SellTicket sellTicket = (SellTicket)Proxy.newProxyInstance(trainStation.getClass().getClassLoader(), trainStation.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * @param proxy 代理對(duì)象 proxyObject是同一個(gè)對(duì)象,在invoke方法中基本不用
                     * @param method 對(duì)接口中的方法進(jìn)行封裝的method對(duì)象
                     * @param args 調(diào)用方法的實(shí)際參數(shù)
                     * @return 方法返回值
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    	 // 代碼增強(qiáng)
                        System.out.println("代理點(diǎn)收取服務(wù)費(fèi)");
                        Object object = method.invoke(trainStation, args);
                        return object;
                    }
                });
        return sellTicket;
    }
    public static void main(String[] args) {
        ProxyFactory proxyPoint = new ProxyFactory();
        SellTicket sellTicket = proxyPoint.getProxyPoint();
        sellTicket.sell();
    }
}

3.3 cglib動(dòng)態(tài)代理

<!-- 引入cglib依賴包-->
<dependency>
     <groupId>cglib</groupId>
     <artifactId>cglib</artifactId>
     <version>2.2.2</version>
 </dependency>
package com.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 ProxyFactory implements MethodInterceptor {
    private TrainStation trainStation = new TrainStation();
    public TrainStation getTrainStation(){
        //創(chuàng)建Enhancer對(duì)象,類似于JDK代理中的Proxy類
        Enhancer enhancer = new Enhancer();
        //設(shè)置父類的字節(jié)碼對(duì)象
        enhancer.setSuperclass(TrainStation.class);
        //設(shè)置回調(diào)函數(shù)
        enhancer.setCallback(this);
        //創(chuàng)建代理對(duì)象
        TrainStation trainStation = (TrainStation)enhancer.create();
        return trainStation;
    }
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    	// 代碼增強(qiáng)
        System.out.println("代售點(diǎn)收取服務(wù)費(fèi)用");
        Object obj = method.invoke(trainStation, objects);
        return obj;
    }
    public static void main(String[] args) throws Exception {
        ProxyFactory proxyFactory = new ProxyFactory();
        TrainStation trainStation = proxyFactory.getTrainStation();
        trainStation.sell();
    }
}

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

相關(guān)文章

  • mybatis 使用jdbc.properties文件設(shè)置不起作用的解決方法

    mybatis 使用jdbc.properties文件設(shè)置不起作用的解決方法

    這篇文章主要介紹了mybatis 使用jdbc.properties文件設(shè)置不起作用的解決方法,需要的朋友可以參考下
    2018-03-03
  • Eclipse中創(chuàng)建Web項(xiàng)目最新方法(2023年)

    Eclipse中創(chuàng)建Web項(xiàng)目最新方法(2023年)

    在Java開(kāi)發(fā)人員中,最常用的開(kāi)發(fā)工具應(yīng)該就是Eclipse,下面這篇文章主要給大家介紹了關(guān)于Eclipse中創(chuàng)建Web項(xiàng)目2023年最新的方法,需要的朋友可以參考下
    2023-09-09
  • shiro整合springboot前后端分離

    shiro整合springboot前后端分離

    這篇文章主要介紹了shiro整合springboot前后端分離,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • Java設(shè)計(jì)模式中的外觀模式詳解

    Java設(shè)計(jì)模式中的外觀模式詳解

    外觀模式為多個(gè)復(fù)雜的子系統(tǒng),提供了一個(gè)一致的界面,使得調(diào)用端只和這個(gè)接口發(fā)生調(diào)用,而無(wú)須關(guān)系這個(gè)子系統(tǒng)內(nèi)部的細(xì)節(jié)。本文將通過(guò)示例詳細(xì)為大家講解一下外觀模式,需要的可以參考一下
    2023-02-02
  • Java Dubbo框架知識(shí)點(diǎn)梳理

    Java Dubbo框架知識(shí)點(diǎn)梳理

    這篇文章主要介紹了Java Dubbo框架知識(shí)點(diǎn)梳理,通過(guò)詳細(xì)的文字講解和代碼實(shí)例,梳理了Dubbo這個(gè)框架,需要的朋友可以參考下
    2021-06-06
  • Java反射之深入理解

    Java反射之深入理解

    這篇文章主要介紹了Java反射機(jī)制的深入理解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Java實(shí)現(xiàn)圖片旋轉(zhuǎn)、指定圖像大小和水平翻轉(zhuǎn)

    Java實(shí)現(xiàn)圖片旋轉(zhuǎn)、指定圖像大小和水平翻轉(zhuǎn)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)圖像旋轉(zhuǎn),指定圖像大小,水平翻轉(zhuǎn)圖像,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • Java如何實(shí)現(xiàn)登錄token令牌

    Java如何實(shí)現(xiàn)登錄token令牌

    這篇文章主要介紹了Java如何實(shí)現(xiàn)登錄token令牌,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Java線程中的interrupt詳解

    Java線程中的interrupt詳解

    這篇文章主要介紹了Java線程中的interrupt詳解,interrupt翻譯成中文為“打斷”的意思,但實(shí)際上,interrupt()方法并非將一個(gè)線程打中斷的意思,本文提供了部分實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2023-09-09
  • SpringCloud-Alibaba-Sentinel-配置持久化策略詳解

    SpringCloud-Alibaba-Sentinel-配置持久化策略詳解

    這篇文章主要介紹了SpringCloud-Alibaba-Sentinel-配置持久化策略,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03

最新評(píng)論