91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java?JDK與cglib動態代理有哪些區別

發布時間:2023-03-20 10:58:57 來源:億速云 閱讀:97 作者:iii 欄目:開發技術

本篇內容主要講解“Java JDK與cglib動態代理有哪些區別”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java JDK與cglib動態代理有哪些區別”吧!

一、說明

1.spring aop中的動態代理主要有兩種方式,jdk動態代理和cglib動態代理

2.從實現接口、繼承父類的角度討論區別

3.從限制角度討論區別

4.從性能上討論區別

二、區別

1.jdk動態代理只提供實現接口的目標類代理,不支持沒有實現接口的目標類的代理。如果目標類沒有實現接口,只能用cglib代理

2.jdk動態代理會在運行時為目標類生成一個動態代理類$proxy*.class。cglib的底層是通過ASM在運行時動態生成目標類的子類,還會有其它類

3. jdk動態代理的代理類實現了目標類實現的接口,并且會實現接口所有方法來代碼增強。cglib動態代理會重寫父類所有的方法來代碼增強

4.jdk動態代理調用時先去調用處理類進行增強,再通過反射的方式調用目標類的方法。cglib動態代理調用時先通過代理類進行增強,再直接調用父類對應的方法進行調用目標方法

5.jdk動態代理如果目標類未實現接口則無法代理,cglib是通過繼承的方式來動態代理,若目標類被final關鍵字修飾,則無法使用cglib做動態代理

6.性能上:在老版的jdk,jdk代理生成的類速度快,通過反射調用慢,cglib是jdk代理速度的10倍左右,jdk在版本每次升級都會有很大的性能提升,cglib停滯不前,jdk7 8的動態代理性能在1萬次實驗中比cglib要快20%左右

三、代碼示例

3.1 靜態代理

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{
    //聲明火車類對象
    private TrainStation trainStation = new TrainStation();
    @Override
    public void sell() {
        System.out.println("代售點收取服務費");
        trainStation.sell();
    }
    public static void main(String[] args) {
        ProxyPoint proxyPoint = new ProxyPoint();
        proxyPoint.sell();
    }
}

3.2 jdk動態代理

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: 類加載器,用于加載代理類。可以通過目標對象獲取類加載器
         * Class<?>[] interfaces: 代理類實現的接口的字節碼對象
         * InvocationHandler h: 代理對象的調用處理程序
         */
        SellTicket sellTicket = (SellTicket)Proxy.newProxyInstance(trainStation.getClass().getClassLoader(), trainStation.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * @param proxy 代理對象 proxyObject是同一個對象,在invoke方法中基本不用
                     * @param method 對接口中的方法進行封裝的method對象
                     * @param args 調用方法的實際參數
                     * @return 方法返回值
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    	 // 代碼增強
                        System.out.println("代理點收取服務費");
                        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動態代理

<!-- 引入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(){
        //創建Enhancer對象,類似于JDK代理中的Proxy類
        Enhancer enhancer = new Enhancer();
        //設置父類的字節碼對象
        enhancer.setSuperclass(TrainStation.class);
        //設置回調函數
        enhancer.setCallback(this);
        //創建代理對象
        TrainStation trainStation = (TrainStation)enhancer.create();
        return trainStation;
    }
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    	// 代碼增強
        System.out.println("代售點收取服務費用");
        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();
    }
}

到此,相信大家對“Java JDK與cglib動態代理有哪些區別”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

仲巴县| 兴化市| 兴和县| 定西市| 龙海市| 济宁市| 湖南省| 贺州市| 盈江县| 微山县| 巴林左旗| 迁安市| 合江县| 石狮市| 玛纳斯县| 勐海县| 新沂市| 琼结县| 鞍山市| 富源县| 左云县| 徐闻县| 新乐市| 太和县| 临清市| 石棉县| 屯门区| 泰宁县| 巢湖市| 吉水县| 莱阳市| 紫金县| 政和县| 封丘县| 洛阳市| 达拉特旗| 枝江市| 石台县| 读书| 得荣县| 霍邱县|