在運行時期能夠按照Java虛擬機規範對class文件的組織規則生成對應的二進制字節碼。當前有不少開源框架能夠完成這些功能,如ASM,Javassist。java
動態代理機制詳解(JDK 和CGLIB,Javassist,ASM)緩存
ASM,Javassist:在代碼裏生成字節碼,並動態地加載成class對象、建立實例。即在運行期系統中,遵循Java編譯系統組織.class文件的格式和結構,生成相應的二進制數據,而後再把這個二進制數據加載轉換成對應的類,這樣,就完成了在代碼中,動態建立一個類的能力了。框架
ASM:ui
ASM 是一個 Java 字節碼操控框架。它可以以二進制形式修改已有類或者動態生成類。ASM 能夠直接產生二進制 class 文件,也能夠在類被加載入 Java 虛擬機以前動態改變類行爲。ASM 從類文件中讀入信息後,可以改變類行爲,分析類信息,甚至可以根據用戶要求生成新類。編碼
不過ASM在建立class字節碼的過程當中,操縱的級別是底層JVM的彙編指令級別,這要求ASM使用者要對class組織結構和JVM彙編指令有必定的瞭解。lua
Javassist:直接使用java編碼的形式,不須要了解虛擬機指令.net
JDK動態代理,CGLIB:不用寫JVM的彙編指令和類的java編碼,經過實現接口和繼承的方式建立。代理
JDK動態代理: 某個類必須有實現的接口,而生成的代理類也只能代理某個類接口定義的方法。若是某個類沒有實現接口,那麼這個類就不能同JDK產生動態代理了。htm
CGLIB:經過繼承完成並且效率比JDK動態代理高。對象
jdk動態代理是由java內部的反射機制來實現的,cglib動態代理底層則是藉助asm來實現的。總的來講,反射機制在生成類的過程當中比較高效,而asm在生成類以後的相關執行過程當中比較高效(能夠經過將asm生成的類進行緩存,這樣解決asm生成類過程低效問題)。還有一點必須注意:jdk動態代理的應用前提,必須是目標類基於統一的接口。若是沒有上述前提,jdk動態代理不能應用。由此能夠看出,jdk動態代理有必定的侷限性,cglib這種第三方類庫實現的動態代理應用更加普遍,且在效率上更有優點。。
http://blog.csdn.net/heyutao007/article/details/49738887
java動態代理:
好比如今想爲RealSubject這個類建立一個動態代理對象,JDK主要會作如下工做:
1. 獲取 RealSubject上的全部接口列表;
2. 肯定要生成的代理類的類名,默認爲:com.sun.proxy.$ProxyXXXX ;3. 根據須要實現的接口信息,在代碼中動態建立 該Proxy類的字節碼;
4 . 將對應的字節碼轉換爲對應的class 對象;
5. 建立InvocationHandler 實例handler,用來處理Proxy全部方法調用;
6. Proxy 的class對象 以建立的handler對象爲參數,實例化一個proxy對象
1.Interface A
2.Class B impl A
3.MyInvocationHandler impl InvocationHandler{
private Object target;//B
invoke(...){
method.invoke(target, args);
4.Class main(){
A a = new B();
InvocationHandler h = new MyInvocationHandler(a);
A proxy = (A)Proxy.newProxyInstance(a.getClass().getClassLoader(), a.getClass().getInterfaces(), h);