jdk動態代理和cglib動態代理

jdk動態代理

我的的理解,運行期間由JVM根據反射等機制動態的生成代理類java

核心API

java.lang.reflect.Proxy  框架

全部動態代理類的父類,它提供了一組靜態方法來爲一組接口動態地生成代理類及其對象。

java.lang.reflect.InvocationHandler 函數

這是調用處理器接口,它自定義了一個 invoke 方法,一般在該方法中實現對委託類的訪問

java.lang.ClassLoader spa

這是類裝載器類,負責將類的字節碼裝載到 Java 虛擬機(JVM)中併爲其定義類對象,而後該類才能被使用

實現一個動態代理

代碼實現:點擊下載代理

一個典型的動態代理建立對象過程可分爲如下四個步驟: code

1. 經過實現InvocationHandler接口建立本身的調用處理器 
IvocationHandler handler = new InvocationHandlerImpl(…);
2. 經過爲Proxy類指定ClassLoader對象和一組interface建立動態代理類
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});
3. 經過反射機制獲取動態代理類的構造函數,其參數類型是調用處理器接口類型
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
4. 經過構造函數建立代理類實例,此時需將調用處理器對象做爲參數被傳入 Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));

爲了簡化對象建立過程,Proxy類中的newInstance方法封裝了2~4,只需兩步便可完成代理對象的建立。 對象

核心問題

1.代理對象是怎麼生成的blog

由Proxy完成, 在內部方法中調用ProxyGenerator類的靜態方法generateProxyClass,這裏是真正生成代理類class字節碼的地方。 

2.InvocationHandler的invoke方法是由誰來調用的繼承

生成的代理類ProxySubject繼承Proxy類實現Subject接口,實現了Subject的方法,在實現方法中,調用處理器的invoke方法

3.真實實例的方法如何被調用的索引

InvocationHander的實現類只是經過代理類的構造函數注入後, 實現了對代理類中方法調用的攔截

而invoke方法利用反射調用的是真實對象的的方法(Object result=method.invoke(proxied,args))

總結

jdk動態代理只能代理接口,是由於生成的代理類自己 extends Proxy  implement  xxxInterface

 cglib動態代理

CGLib採用了asm框架的字節碼技術,其原理是:

經過字節碼技術爲一個類建立子類,並在子類中採用方法攔截的技術攔截全部父類方法的調用,順勢織入橫切邏輯

 核心API

 net.sf.cglib.proxy.Enhancer – 主要的加強類

net.sf.cglib.proxy.MethodInterceptor – 主要的方法攔截類,它是Callback接口的子接口,須要用戶實現

net.sf.cglib.proxy.MethodProxy  -能夠方便的實現對源對象方法的調用

實現一個動態代理

代碼實現: 點擊下載

核心問題

1.代理對象的生成過程由Enhancer類實現

一、生成代理類Class的二進制字節碼;
二、經過Class.forName加載二進制字節碼,生成Class對象;
三、經過反射機制獲取實例構造,並初始化代理類對象。

2.如何調用真實實例的方法

經過FastClassInfo維護了委託類和代理類的FastClass,提出下標概念index,經過索引保存方法的引用信息,將原先的反射調用,轉化爲方法的直接調用
因此當調用方法時,其實是調用代理類的方法,直接調用了委託類的add方法。methodProxy.invokeSuperCGLIB$add$0CGLIB$add$0

總結

cglib動態代理類,繼承了委託類, 採用保存索引的方式調用委託類的方法

Jdk動態代理和cglib動態代理的區別

一、jdk動態代理生成的代理類和委託類實現了相同的接口;
二、cglib動態代理中生成的字節碼更加複雜,生成的代理類是委託類的子類,且不能處理被final關鍵字修飾的方法;
三、jdk採用反射機制調用委託類的方法,cglib採用相似索引的方式直接調用委託類方法

相關文章
相關標籤/搜索