Java中Cglib代理和JDK代理的區(qū)別詳解
一、JDK
Jdk動態(tài)代理,拿到目標(biāo)類所實現(xiàn)的接口(目標(biāo)類必須有實現(xiàn)接口),生成代理類,并且代理類也會實現(xiàn)和目標(biāo)類一樣的接口。
二、Cglib
Cglib代理功能更強(qiáng),無論目標(biāo)類是否實現(xiàn)了接口都可以代理,他是基于繼承的方式來代理目標(biāo)類,如果目標(biāo)類也實現(xiàn)了接口,代理類也會實現(xiàn)一次
public Object getProxy(@Nullable ClassLoader classLoader) { Class<?> rootClass = this.advised.getTargetClass();//目標(biāo)類 Class<?> proxySuperClass = rootClass; if (rootClass.getName().contains("$$")) { //如果目標(biāo)類也是一個代理類,那么就拿到這個代理類的父類,因為這個代理類的父類,才是我們真正要代理的目標(biāo)類。然后繼承他 proxySuperClass = rootClass.getSuperclass(); Class<?>[] additionalInterfaces = rootClass.getInterfaces();//如果目標(biāo)類是一個代理類,那么這個代理實現(xiàn)的接口,也就是新的代理類要實現(xiàn)的接口。 this.advised.addInterface(additionalInterfaces); 把接口存起來下面要用 } Enhancer enhancer = this.createEnhancer(); enhancer.setSuperclass(proxySuperClass); //設(shè)置代理的父類,可能是目標(biāo)類的類型,可能是目標(biāo)類的父類。 enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); //設(shè)置新的代理類要實現(xiàn)的接口。 //必實現(xiàn)的接口SpringProxy,如果是切面還會實現(xiàn)Advised enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader)); Callback[] callbacks = this.getCallbacks(rootClass); Class<?>[] types = new Class[callbacks.length]; 。。。。。 }
三、如何選擇
那么在Spring創(chuàng)建代理對象的時候是選擇Cglib還是Jdk有一段代碼
//判斷是否是接口或者是否是代理類 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { new JdkDynamicAopProxy(config) } else { new ObjenesisCglibAopProxy(config) } public static boolean isProxyClass(Class<?> cl) { return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl); }
Proxy.class.isAssignableFrom(cl)就是判斷cl所表示的類是不是SpringProxy或者SpringProxy的子類。因為所有的代理類都會繼承SpringProxy,所以這個條件必須滿足。滿足這個條件也不能保證就是代理類,因為可能存在人為地編寫一個類繼承SpringProxy。proxyClassCache.containsValue(cl)這個方法是檢查緩存中是否存在這個Class實例cl。只要生成過代理類都會被緩存,所以這個方法才是檢測一個類是否是代理類的唯一標(biāo)準(zhǔn)。
到此這篇關(guān)于Java中Cglib代理和JDK代理的區(qū)別詳解的文章就介紹到這了,更多相關(guān)Cglib代理和JDK代理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot實現(xiàn)Read Through模式的操作過程
Read Through模式通常是指一種緩存策略,其中當(dāng)應(yīng)用程序嘗試讀取數(shù)據(jù)時,緩存系統(tǒng)首先被檢查以查看數(shù)據(jù)是否已經(jīng)存在于緩存中,這篇文章主要介紹了SpringBoot實現(xiàn)Read Through模式,需要的朋友可以參考下2024-07-07IntelliJ IDEA右鍵文件夾沒有Java Class文件的原因及解決方法
這篇文章主要介紹了IntelliJ IDEA右鍵文件夾沒有Java Class文件的原因及解決方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09java獲得平臺相關(guān)的行分隔符和java路徑分隔符的方法
不同系統(tǒng)平臺下的行分隔符、路徑分隔符等常常不同,如何在Java程序獲取當(dāng)前平臺的分隔符,以及其他系統(tǒng)相關(guān)的狀態(tài)呢?下面是示例程序,需要的朋友可以參考下2014-02-02SpringBoot集成ShardingSphere實現(xiàn)數(shù)據(jù)庫分表
ShardingSphere?是一個開源的分布式數(shù)據(jù)庫中間件,旨在為應(yīng)用提供數(shù)據(jù)庫分片、讀寫分離、分布式事務(wù)等功能,下面我們來看看SpringBoot如何集成ShardingSphere實現(xiàn)數(shù)據(jù)庫分表吧2024-12-12Java實現(xiàn)解壓zip壓縮包的兩種方法(支持多層級)
壓縮文件在生活中經(jīng)常能用到,在Java中提供了壓縮和解壓縮文件的功能,本文主要介紹了Java實現(xiàn)解壓zip壓縮包的兩種方法(支持多層級),感興趣的可以了解一下2024-03-03