您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Java JDK與cglib動態(tài)代理有哪些區(qū)別”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java JDK與cglib動態(tài)代理有哪些區(qū)別”吧!
1.spring aop中的動態(tài)代理主要有兩種方式,jdk動態(tài)代理和cglib動態(tài)代理
2.從實現(xiàn)接口、繼承父類的角度討論區(qū)別
3.從限制角度討論區(qū)別
4.從性能上討論區(qū)別
1.jdk動態(tài)代理只提供實現(xiàn)接口的目標類代理,不支持沒有實現(xiàn)接口的目標類的代理。如果目標類沒有實現(xiàn)接口,只能用cglib代理
2.jdk動態(tài)代理會在運行時為目標類生成一個動態(tài)代理類$proxy*.class。cglib的底層是通過ASM在運行時動態(tài)生成目標類的子類,還會有其它類
3. jdk動態(tài)代理的代理類實現(xiàn)了目標類實現(xiàn)的接口,并且會實現(xiàn)接口所有方法來代碼增強。cglib動態(tài)代理會重寫父類所有的方法來代碼增強
4.jdk動態(tài)代理調(diào)用時先去調(diào)用處理類進行增強,再通過反射的方式調(diào)用目標類的方法。cglib動態(tài)代理調(diào)用時先通過代理類進行增強,再直接調(diào)用父類對應(yīng)的方法進行調(diào)用目標方法
5.jdk動態(tài)代理如果目標類未實現(xiàn)接口則無法代理,cglib是通過繼承的方式來動態(tài)代理,若目標類被final關(guān)鍵字修飾,則無法使用cglib做動態(tài)代理
6.性能上:在老版的jdk,jdk代理生成的類速度快,通過反射調(diào)用慢,cglib是jdk代理速度的10倍左右,jdk在版本每次升級都會有很大的性能提升,cglib停滯不前,jdk7 8的動態(tài)代理性能在1萬次實驗中比cglib要快20%左右
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("代售點收取服務(wù)費"); trainStation.sell(); } public static void main(String[] args) { ProxyPoint proxyPoint = new ProxyPoint(); proxyPoint.sell(); } }
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: 代理類實現(xiàn)的接口的字節(jié)碼對象 * InvocationHandler h: 代理對象的調(diào)用處理程序 */ SellTicket sellTicket = (SellTicket)Proxy.newProxyInstance(trainStation.getClass().getClassLoader(), trainStation.getClass().getInterfaces(), new InvocationHandler() { /** * @param proxy 代理對象 proxyObject是同一個對象,在invoke方法中基本不用 * @param method 對接口中的方法進行封裝的method對象 * @param args 調(diào)用方法的實際參數(shù) * @return 方法返回值 * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 代碼增強 System.out.println("代理點收取服務(wù)費"); 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(); } }
<!-- 引入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對象,類似于JDK代理中的Proxy類 Enhancer enhancer = new Enhancer(); //設(shè)置父類的字節(jié)碼對象 enhancer.setSuperclass(TrainStation.class); //設(shè)置回調(diào)函數(shù) enhancer.setCallback(this); //創(chuàng)建代理對象 TrainStation trainStation = (TrainStation)enhancer.create(); return trainStation; } public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { // 代碼增強 System.out.println("代售點收取服務(wù)費用"); 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動態(tài)代理有哪些區(qū)別”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。