Java 動態代理的實現

在Java中可以實現動態代理的方式有很多種:JDK方式、ASM字節碼操控框架、開源的分析、編輯和創建Java字節碼的類庫Javassist、基於ASM框架實現的CGLIB

JDK方式:通過Java反射的方式生成動態代理類。

缺點:JDK中提供的生成動態代理類的機制有個鮮明的特點是: 某個類必須有實現的接口,而生成的代理類也只能代理某個類接口定義的方法。更極端的情況是:如果某個類沒有實現接口,那麼這個類就不能同JDK產生動態代理了。

ASM方式:ASM 是一個 Java 字節碼操控框架。它能夠以二進制形式修改已有類或者動態生成類。ASM 可以直接產生二進制 class 文件,也可以在類被加載入 Java 虛擬機之前動態改變類行爲。ASM 從類文件中讀入信息後,能夠改變類行爲,分析類信息,甚至能夠根據用戶要求生成新類。

缺點:ASM在創建class字節碼的過程中,操縱的級別是底層JVM的彙編指令級別,這要求ASM使用者要對class組織結構和JVM彙編指令有一定的瞭解。

Javassist方式:Javassist是一個開源的分析、編輯和創建Java字節碼的類庫。是由東京工業大學的數學和計算機科學系的 Shigeru Chiba (千葉 滋)所創建的。它已加入了開放源代碼JBoss 應用服務器項目,通過使用Javassist對字節碼操作爲JBoss實現動態AOP框架。javassist是jboss的一個子項目,其主要的優點,在於簡單,而且快速。直接使用java編碼的形式,而不需要了解虛擬機指令,就能動態改變類的結構,或者動態生成類。

優點:使用Javassist對字節碼操作進行代理實現效率和ASM方式不相上下。

缺點:其實現相當地麻煩,在創造的過程中,含有太多的業務代碼。我們創建Proxy代理類的方式的初衷是減少系統代碼的冗雜度,但是javassist做法卻增加了在動態創建代理類過程中的複雜度:手動地創建了太多的業務代碼,並且封裝性也不夠,完全不具有可拓展性和通用性。如果某個代理類的一些業務邏輯非常複雜,上述的動態創建代理的方式是非常不可取的。

CGLIB方式:CGLIB(Code Generation Library)是一個強大的,高性能,高質量的Code生成類庫,它可以在運行期擴展Java類與實現Java接口。這也是CGLIB比JDK的代理類的強大之處,不只可以實現接口,還可以擴展類,解決了有的類由於沒有實現接口而無法被動態代理的問題。另外,CGLIB底層封裝了ASM,通過對字節碼的操作來生成類,具有更高的性能。

缺點:由於底層實現問題,反射機制在生成類的過程中比較高效,而asm在生成類之後的相關執行過程中比較高效(可以通過將asm生成的類進行緩存,這樣解決asm生成類過程低效問題),所以CGLIB和ASM的代理都存在生成代理類低效的問題。並且由於CGLIB的代理實現方式爲生成被代理類的繼承,因此對於final方法的代理無能爲力。

---------------------------------------------------------------------------------------------------------------------------------

以下內容來自網絡帖子:轉載自 http://javatar.iteye.com/blog/814426/

動態代理工具比較成熟的產品有: 
JDK自帶的,ASM,CGLIB(基於ASM包裝),JAVAASSIST, 
使用的版本分別爲: 
JDK-1.6.0_18-b07, ASM-3.3, CGLIB-2.2, JAVAASSIST-3.11.0.GA 

(一) 測試結果: 
數據爲執行三次,每次調用一千萬次代理方法的結果,測試代碼後面有貼出。 

(1) PC機測試結果:Linux 2.6.9-42.ELsmp(32bit), 2 Cores CPU(Intel Pentium4 3.06GHz) 

測試結果:

Create JDK Proxy: 13 ms  
Create CGLIB Proxy: 217 ms  
Create JAVAASSIST Proxy: 99 ms  
Create JAVAASSIST Bytecode Proxy: 168 ms  
Create ASM Proxy: 3 ms  
================  
Run JDK Proxy: 2224 ms, 634,022 t/s  
Run CGLIB Proxy: 1123 ms, 1,255,623 t/s  
Run JAVAASSIST Proxy: 3212 ms, 438,999 t/s  
Run JAVAASSIST Bytecode Proxy: 206 ms, 6,844,977 t/s  
Run ASM Bytecode Proxy: 209 ms, 6,746,724 t/s  
----------------  
Run JDK Proxy: 2169 ms, 650,099 t/s  
Run CGLIB Proxy: 1059 ms, 1,331,506 t/s  
Run JAVAASSIST Proxy: 3328 ms, 423,697 t/s  
Run JAVAASSIST Bytecode Proxy: 202 ms, 6,980,521 t/s  
Run ASM Bytecode Proxy: 206 ms, 6,844,977 t/s  
----------------  
Run JDK Proxy: 2174 ms, 648,604 t/s  
Run CGLIB Proxy: 1032 ms, 1,366,342 t/s  
Run JAVAASSIST Proxy: 3119 ms, 452,088 t/s  
Run JAVAASSIST Bytecode Proxy: 207 ms, 6,811,910 t/s  
Run ASM Bytecode Proxy: 207 ms, 6,811,910 t/s  
----------------  

(2) 服務器測試結果:Linux 2.6.18-128.el5xen(64bit), 16 Cores CPU(Intel Xeon E5520 2.27GHz) 

測試結果:

Create JDK Proxy: 7 ms  
Create CGLIB Proxy: 86 ms  
Create JAVAASSIST Proxy: 36 ms  
Create JAVAASSIST Bytecode Proxy: 57 ms  
Create ASM Proxy: 1 ms  
================  
Run JDK Proxy: 235 ms, 6,000,278 t/s  
Run CGLIB Proxy: 234 ms, 6,025,920 t/s  
Run JAVAASSIST Proxy: 459 ms, 3,072,037 t/s  
Run JAVAASSIST Bytecode Proxy: 71 ms, 19,860,076 t/s  
Run ASM Bytecode Proxy: 72 ms, 19,584,241 t/s  
----------------  
Run JDK Proxy: 298 ms, 4,731,763 t/s  
Run CGLIB Proxy: 134 ms, 10,522,876 t/s  
Run JAVAASSIST Proxy: 406 ms, 3,473,067 t/s  
Run JAVAASSIST Bytecode Proxy: 67 ms, 21,045,752 t/s  
Run ASM Bytecode Proxy: 66 ms, 21,364,627 t/s  
----------------  
Run JDK Proxy: 282 ms, 5,000,231 t/s  
Run CGLIB Proxy: 133 ms, 10,601,995 t/s  
Run JAVAASSIST Proxy: 406 ms, 3,473,067 t/s  
Run JAVAASSIST Bytecode Proxy: 67 ms, 21,045,752 t/s  
Run ASM Bytecode Proxy: 67 ms, 21,045,752 t/s  
----------------  

(二) 測試結論: 
1. ASM和JAVAASSIST字節碼生成方式不相上下,都很快,是CGLIB的5倍。 
2. CGLIB次之,是JDK自帶的兩倍。 
3. JDK自帶的再次之,因JDK1.6對動態代理做了優化,如果用低版本JDK更慢,要注意的是JDK也是通過字節碼生成來實現動態代理的,而不是反射。 
4. JAVAASSIST提供者動態代理接口最慢,比JDK自帶的還慢。 
(這也是爲什麼網上有人說JAVAASSIST比JDK還慢的原因,用JAVAASSIST最好別用它提供的動態代理接口,而可以考慮用它的字節碼生成方式) 

(三) 差異原因: 
各方案生成的字節碼不一樣, 
像JDK和CGLIB都考慮了很多因素,以及繼承或包裝了自己的一些類, 
所以生成的字節碼非常大,而我們很多時候用不上這些, 
而手工生成的字節碼非常小,所以速度快, 
具體的字節碼對比,後面有貼出,可自行分析。 

(四) 最終選型: 
最終決定使用JAVAASSIST的字節碼生成代理方式, 
雖然ASM稍快,但並沒有快一個數量級, 
而JAVAASSIST的字節碼生成方式比ASM方便, 
JAVAASSIST只需用字符串拼接出Java源碼,便可生成相應字節碼, 
而ASM需要手工寫字節碼。 

(五) 測試代碼: 

public interface CountService {  
  
    int count();  
  
}  


public class CountServiceImpl implements CountService {  
  
    private int count = 0;  
  
    public int count() {  
        return count ++;  
    }  
}  


import java.lang.reflect.Field;  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  
import java.text.DecimalFormat;  
  
import javassist.ClassPool;  
import javassist.CtClass;  
import javassist.CtField;  
import javassist.CtNewConstructor;  
import javassist.CtNewMethod;  
import javassist.util.proxy.MethodHandler;  
import javassist.util.proxy.ProxyFactory;  
import javassist.util.proxy.ProxyObject;  
import net.sf.cglib.proxy.Enhancer;  
import net.sf.cglib.proxy.MethodInterceptor;  
import net.sf.cglib.proxy.MethodProxy;  
  
import org.objectweb.asm.ClassWriter;  
import org.objectweb.asm.FieldVisitor;  
import org.objectweb.asm.MethodVisitor;  
import org.objectweb.asm.Opcodes;  
  
public class DynamicProxyPerformanceTest {  
  
    public static void main(String[] args) throws Exception {  
        CountService delegate = new CountServiceImpl();  
          
        long time = System.currentTimeMillis();  
        CountService jdkProxy = createJdkDynamicProxy(delegate);  
        time = System.currentTimeMillis() - time;  
        System.out.println("Create JDK Proxy: " + time + " ms");  
          
        time = System.currentTimeMillis();  
        CountService cglibProxy = createCglibDynamicProxy(delegate);  
        time = System.currentTimeMillis() - time;  
        System.out.println("Create CGLIB Proxy: " + time + " ms");  
          
        time = System.currentTimeMillis();  
        CountService javassistProxy = createJavassistDynamicProxy(delegate);  
        time = System.currentTimeMillis() - time;  
        System.out.println("Create JAVAASSIST Proxy: " + time + " ms");  
          
        time = System.currentTimeMillis();  
        CountService javassistBytecodeProxy = createJavassistBytecodeDynamicProxy(delegate);  
        time = System.currentTimeMillis() - time;  
        System.out.println("Create JAVAASSIST Bytecode Proxy: " + time + " ms");  
          
        time = System.currentTimeMillis();  
        CountService asmBytecodeProxy = createAsmBytecodeDynamicProxy(delegate);  
        time = System.currentTimeMillis() - time;  
        System.out.println("Create ASM Proxy: " + time + " ms");  
        System.out.println("================");  
          
        for (int i = 0; i < 3; i++) {  
            test(jdkProxy, "Run JDK Proxy: ");  
            test(cglibProxy, "Run CGLIB Proxy: ");  
            test(javassistProxy, "Run JAVAASSIST Proxy: ");  
            test(javassistBytecodeProxy, "Run JAVAASSIST Bytecode Proxy: ");  
            test(asmBytecodeProxy, "Run ASM Bytecode Proxy: ");  
            System.out.println("----------------");  
        }  
    }  
  
    private static void test(CountService service, String label)  
            throws Exception {  
        service.count(); // warm up  
        int count = 10000000;  
        long time = System.currentTimeMillis();  
        for (int i = 0; i < count; i++) {  
            service.count();  
        }  
        time = System.currentTimeMillis() - time;  
        System.out.println(label + time + " ms, " + new DecimalFormat().format(count * 1000 / time) + " t/s");  
    }  
  
    private static CountService createJdkDynamicProxy(final CountService delegate) {  
        CountService jdkProxy = (CountService) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),  
                new Class[] { CountService.class }, new JdkHandler(delegate));  
        return jdkProxy;  
    }  
      
    private static class JdkHandler implements InvocationHandler {  
  
        final Object delegate;  
  
        JdkHandler(Object delegate) {  
            this.delegate = delegate;  
        }  
  
        public Object invoke(Object object, Method method, Object[] objects)  
                throws Throwable {  
            return method.invoke(delegate, objects);  
        }  
    }  
  
    private static CountService createCglibDynamicProxy(final CountService delegate) throws Exception {  
        Enhancer enhancer = new Enhancer();  
        enhancer.setCallback(new CglibInterceptor(delegate));  
        enhancer.setInterfaces(new Class[] { CountService.class });  
        CountService cglibProxy = (CountService) enhancer.create();  
        return cglibProxy;  
    }  
  
    private static class CglibInterceptor implements MethodInterceptor {  
          
        final Object delegate;  
  
        CglibInterceptor(Object delegate) {  
            this.delegate = delegate;  
        }  
  
        public Object intercept(Object object, Method method, Object[] objects,  
                MethodProxy methodProxy) throws Throwable {  
            return methodProxy.invoke(delegate, objects);  
        }  
    }  
  
    private static CountService createJavassistDynamicProxy(final CountService delegate) throws Exception {  
        ProxyFactory proxyFactory = new ProxyFactory();  
        proxyFactory.setInterfaces(new Class[] { CountService.class });  
        Class<?> proxyClass = proxyFactory.createClass();  
        CountService javassistProxy = (CountService) proxyClass.newInstance();  
        ((ProxyObject) javassistProxy).setHandler(new JavaAssitInterceptor(delegate));  
        return javassistProxy;  
    }  
  
    private static class JavaAssitInterceptor implements MethodHandler {  
  
        final Object delegate;  
  
        JavaAssitInterceptor(Object delegate) {  
            this.delegate = delegate;  
        }  
  
        public Object invoke(Object self, Method m, Method proceed,  
                Object[] args) throws Throwable {  
            return m.invoke(delegate, args);  
        }  
    }  
  
    private static CountService createJavassistBytecodeDynamicProxy(CountService delegate) throws Exception {  
        ClassPool mPool = new ClassPool(true);  
        CtClass mCtc = mPool.makeClass(CountService.class.getName() + "JavaassistProxy");  
        mCtc.addInterface(mPool.get(CountService.class.getName()));  
        mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc));  
        mCtc.addField(CtField.make("public " + CountService.class.getName() + " delegate;", mCtc));  
        mCtc.addMethod(CtNewMethod.make("public int count() { return delegate.count(); }", mCtc));  
        Class<?> pc = mCtc.toClass();  
        CountService bytecodeProxy = (CountService) pc.newInstance();  
        Field filed = bytecodeProxy.getClass().getField("delegate");  
        filed.set(bytecodeProxy, delegate);  
        return bytecodeProxy;  
    }  
      
    private static CountService createAsmBytecodeDynamicProxy(CountService delegate) throws Exception {  
        ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);  
        String className = CountService.class.getName() +  "AsmProxy";  
        String classPath = className.replace('.', '/');  
        String interfacePath = CountService.class.getName().replace('.', '/');  
        classWriter.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, classPath, null, "java/lang/Object", new String[] {interfacePath});  
          
        MethodVisitor initVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);  
        initVisitor.visitCode();  
        initVisitor.visitVarInsn(Opcodes.ALOAD, 0);  
        initVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");  
        initVisitor.visitInsn(Opcodes.RETURN);  
        initVisitor.visitMaxs(0, 0);  
        initVisitor.visitEnd();  
          
        FieldVisitor fieldVisitor = classWriter.visitField(Opcodes.ACC_PUBLIC, "delegate", "L" + interfacePath + ";", null, null);  
        fieldVisitor.visitEnd();  
          
        MethodVisitor methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "count", "()I", null, null);  
        methodVisitor.visitCode();  
        methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);  
        methodVisitor.visitFieldInsn(Opcodes.GETFIELD, classPath, "delegate", "L" + interfacePath + ";");  
        methodVisitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, interfacePath, "count", "()I");  
        methodVisitor.visitInsn(Opcodes.IRETURN);  
        methodVisitor.visitMaxs(0, 0);  
        methodVisitor.visitEnd();  
          
        classWriter.visitEnd();  
        byte[] code = classWriter.toByteArray();  
        CountService bytecodeProxy = (CountService) new ByteArrayClassLoader().getClass(className, code).newInstance();  
        Field filed = bytecodeProxy.getClass().getField("delegate");  
        filed.set(bytecodeProxy, delegate);  
        return bytecodeProxy;  
    }  
      
    private static class ByteArrayClassLoader extends ClassLoader {  
  
        public ByteArrayClassLoader() {  
            super(ByteArrayClassLoader.class.getClassLoader());  
        }  
  
        public synchronized Class<?> getClass(String name, byte[] code) {  
            if (name == null) {  
                throw new IllegalArgumentException("");  
            }  
            return defineClass(name, code, 0, code.length);  
        }  
  
    }  
}  

(六) 字節碼對比 

(1) JDK生成的字節碼: 

public final class $Proxy0 extends java.lang.reflect.Proxy implements com.alibaba.test.performance.dynamicproxy.CountService{  
public $Proxy0(java.lang.reflect.InvocationHandler)   throws ;  
  Code:  
   0:   aload_0  
   1:   aload_1  
   2:   invokespecial   #8; //Method java/lang/reflect/Proxy."":(Ljava/lang/reflect/InvocationHandler;)V  
   5:   return  
  
public final boolean equals(java.lang.Object)   throws ;  
  Code:  
   0:   aload_0  
   1:   getfield    #16; //Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;  
   4:   aload_0  
   5:   getstatic   #20; //Field m1:Ljava/lang/reflect/Method;  
   8:   iconst_1  
   9:   anewarray   #22; //class java/lang/Object  
   12:  dup  
   13:  iconst_0  
   14:  aload_1  
   15:  aastore  
   16:  invokeinterface #28,  4; //InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
   21:  checkcast   #30; //class java/lang/Boolean  
   24:  invokevirtual   #34; //Method java/lang/Boolean.booleanValue:()Z  
   27:  ireturn  
   28:  athrow  
   29:  astore_2  
   30:  new #42; //class java/lang/reflect/UndeclaredThrowableException  
   33:  dup  
   34:  aload_2  
   35:  invokespecial   #45; //Method java/lang/reflect/UndeclaredThrowableException."":(Ljava/lang/Throwable;)V  
   38:  athrow  
  Exception table:  
   from   to  target type  
     0    28    28   Class java/lang/Error  
  
     0    28    28   Class java/lang/RuntimeException  
  
     0    28    29   Class java/lang/Throwable  
  
  
public final int count()   throws ;  
  Code:  
   0:   aload_0  
   1:   getfield    #16; //Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;  
   4:   aload_0  
   5:   getstatic   #50; //Field m3:Ljava/lang/reflect/Method;  
   8:   aconst_null  
   9:   invokeinterface #28,  4; //InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
   14:  checkcast   #52; //class java/lang/Integer  
   17:  invokevirtual   #55; //Method java/lang/Integer.intValue:()I  
   20:  ireturn  
   21:  athrow  
   22:  astore_1  
   23:  new #42; //class java/lang/reflect/UndeclaredThrowableException  
   26:  dup  
   27:  aload_1  
   28:  invokespecial   #45; //Method java/lang/reflect/UndeclaredThrowableException."":(Ljava/lang/Throwable;)V  
   31:  athrow  
  Exception table:  
   from   to  target type  
     0    21    21   Class java/lang/Error  
  
     0    21    21   Class java/lang/RuntimeException  
  
     0    21    22   Class java/lang/Throwable  
  
  
public final int hashCode()   throws ;  
  Code:  
   0:   aload_0  
   1:   getfield    #16; //Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;  
   4:   aload_0  
   5:   getstatic   #59; //Field m0:Ljava/lang/reflect/Method;  
   8:   aconst_null  
   9:   invokeinterface #28,  4; //InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
   14:  checkcast   #52; //class java/lang/Integer  
   17:  invokevirtual   #55; //Method java/lang/Integer.intValue:()I  
   20:  ireturn  
   21:  athrow  
   22:  astore_1  
   23:  new #42; //class java/lang/reflect/UndeclaredThrowableException  
   26:  dup  
   27:  aload_1  
   28:  invokespecial   #45; //Method java/lang/reflect/UndeclaredThrowableException."":(Ljava/lang/Throwable;)V  
   31:  athrow  
  Exception table:  
   from   to  target type  
     0    21    21   Class java/lang/Error  
  
     0    21    21   Class java/lang/RuntimeException  
  
     0    21    22   Class java/lang/Throwable  
  
  
public final java.lang.String toString()   throws ;  
  Code:  
   0:   aload_0  
   1:   getfield    #16; //Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;  
   4:   aload_0  
   5:   getstatic   #64; //Field m2:Ljava/lang/reflect/Method;  
   8:   aconst_null  
   9:   invokeinterface #28,  4; //InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
   14:  checkcast   #66; //class java/lang/String  
   17:  areturn  
   18:  athrow  
   19:  astore_1  
   20:  new #42; //class java/lang/reflect/UndeclaredThrowableException  
   23:  dup  
   24:  aload_1  
   25:  invokespecial   #45; //Method java/lang/reflect/UndeclaredThrowableException."":(Ljava/lang/Throwable;)V  
   28:  athrow  
  Exception table:  
   from   to  target type  
     0    18    18   Class java/lang/Error  
  
     0    18    18   Class java/lang/RuntimeException  
  
     0    18    19   Class java/lang/Throwable  
  
  
static {}   throws ;  
  Code:  
   0:   ldc #70; //String java.lang.Object  
   2:   invokestatic    #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;  
   5:   ldc #77; //String equals  
   7:   iconst_1  
   8:   anewarray   #72; //class java/lang/Class  
   11:  dup  
   12:  iconst_0  
   13:  ldc #70; //String java.lang.Object  
   15:  invokestatic    #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;  
   18:  aastore  
   19:  invokevirtual   #81; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;  
   22:  putstatic   #20; //Field m1:Ljava/lang/reflect/Method;  
   25:  ldc #83; //String com.alibaba.test.performance.dynamicproxy.CountService  
   27:  invokestatic    #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;  
   30:  ldc #84; //String count  
   32:  iconst_0  
   33:  anewarray   #72; //class java/lang/Class  
   36:  invokevirtual   #81; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;  
   39:  putstatic   #50; //Field m3:Ljava/lang/reflect/Method;  
   42:  ldc #70; //String java.lang.Object  
   44:  invokestatic    #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;  
   47:  ldc #85; //String hashCode  
   49:  iconst_0  
   50:  anewarray   #72; //class java/lang/Class  
   53:  invokevirtual   #81; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;  
   56:  putstatic   #59; //Field m0:Ljava/lang/reflect/Method;  
   59:  ldc #70; //String java.lang.Object  
   61:  invokestatic    #76; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;  
   64:  ldc #86; //String toString  
   66:  iconst_0  
   67:  anewarray   #72; //class java/lang/Class  
   70:  invokevirtual   #81; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;  
   73:  putstatic   #64; //Field m2:Ljava/lang/reflect/Method;  
   76:  return  
   77:  astore_1  
   78:  new #90; //class java/lang/NoSuchMethodError  
   81:  dup  
   82:  aload_1  
   83:  invokevirtual   #93; //Method java/lang/Throwable.getMessage:()Ljava/lang/String;  
   86:  invokespecial   #96; //Method java/lang/NoSuchMethodError."":(Ljava/lang/String;)V  
   89:  athrow  
   90:  astore_1  
   91:  new #100; //class java/lang/NoClassDefFoundError  
   94:  dup  
   95:  aload_1  
   96:  invokevirtual   #93; //Method java/lang/Throwable.getMessage:()Ljava/lang/String;  
   99:  invokespecial   #101; //Method java/lang/NoClassDefFoundError."":(Ljava/lang/String;)V  
   102: athrow  
  Exception table:  
   from   to  target type  
     0    77    77   Class java/lang/NoSuchMethodException  
  
     0    77    90   Class java/lang/ClassNotFoundException  
  
  
}  



(2) CGLIB生成的字節碼: 

public class net.sf.cglib.core.MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7 extends net.sf.cglib.core.KeyFactory implements net.sf.cglib.core.MethodWrapper$MethodWrapperKey{  
public net.sf.cglib.core.MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7();  
  Code:  
   0:   aload_0  
   1:   invokespecial   #11; //Method net/sf/cglib/core/KeyFactory."":()V  
   4:   return  
  
public java.lang.Object newInstance(java.lang.String, java.lang.String[], java.lang.String);  
  Code:  
   0:   new #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7  
   3:   dup  
   4:   aload_1  
   5:   aload_2  
   6:   aload_3  
   7:   invokespecial   #16; //Method "":(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V  
   10:  areturn  
  
public net.sf.cglib.core.MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7(java.lang.String, java.lang.String[], java.lang.String);  
  Code:  
   0:   aload_0  
   1:   invokespecial   #11; //Method net/sf/cglib/core/KeyFactory."":()V  
   4:   aload_0  
   5:   dup  
   6:   aload_1  
   7:   putfield    #20; //Field FIELD_0:Ljava/lang/String;  
   10:  dup  
   11:  aload_2  
   12:  putfield    #24; //Field FIELD_1:[Ljava/lang/String;  
   15:  dup  
   16:  aload_3  
   17:  putfield    #27; //Field FIELD_2:Ljava/lang/String;  
   20:  return  
  
public int hashCode();  
  Code:  
   0:   ldc #30; //int 938313161  
   2:   aload_0  
   3:   getfield    #20; //Field FIELD_0:Ljava/lang/String;  
   6:   swap  
   7:   ldc #31; //int 362693231  
   9:   imul  
   10:  swap  
   11:  dup  
   12:  ifnull  21  
   15:  invokevirtual   #35; //Method java/lang/Object.hashCode:()I  
   18:  goto    23  
   21:  pop  
   22:  iconst_0  
   23:  iadd  
   24:  aload_0  
   25:  getfield    #24; //Field FIELD_1:[Ljava/lang/String;  
   28:  dup  
   29:  ifnull  71  
   32:  astore_1  
   33:  iconst_0  
   34:  istore_2  
   35:  goto    62  
   38:  aload_1  
   39:  iload_2  
   40:  aaload  
   41:  swap  
   42:  ldc #31; //int 362693231  
   44:  imul  
   45:  swap  
   46:  dup  
   47:  ifnull  56  
   50:  invokevirtual   #35; //Method java/lang/Object.hashCode:()I  
   53:  goto    58  
   56:  pop  
   57:  iconst_0  
   58:  iadd  
   59:  iinc    2, 1  
   62:  iload_2  
   63:  aload_1  
   64:  arraylength  
   65:  if_icmplt   38  
   68:  goto    72  
   71:  pop  
   72:  aload_0  
   73:  getfield    #27; //Field FIELD_2:Ljava/lang/String;  
   76:  swap  
   77:  ldc #31; //int 362693231  
   79:  imul  
   80:  swap  
   81:  dup  
   82:  ifnull  91  
   85:  invokevirtual   #35; //Method java/lang/Object.hashCode:()I  
   88:  goto    93  
   91:  pop  
   92:  iconst_0  
   93:  iadd  
   94:  ireturn  
  
public boolean equals(java.lang.Object);  
  Code:  
   0:   aload_1  
   1:   instanceof  #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7  
   4:   ifeq    181  
   7:   aload_0  
   8:   getfield    #20; //Field FIELD_0:Ljava/lang/String;  
   11:  aload_1  
   12:  checkcast   #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7  
   15:  getfield    #20; //Field FIELD_0:Ljava/lang/String;  
   18:  dup2  
   19:  ifnonnull   29  
   22:  ifnonnull   35  
   25:  pop2  
   26:  goto    45  
   29:  ifnull  35  
   32:  goto    39  
   35:  pop2  
   36:  goto    181  
   39:  invokevirtual   #39; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z  
   42:  ifeq    181  
   45:  aload_0  
   46:  getfield    #24; //Field FIELD_1:[Ljava/lang/String;  
   49:  aload_1  
   50:  checkcast   #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7  
   53:  getfield    #24; //Field FIELD_1:[Ljava/lang/String;  
   56:  dup2  
   57:  ifnonnull   67  
   60:  ifnonnull   73  
   63:  pop2  
   64:  goto    141  
   67:  ifnull  73  
   70:  goto    77  
   73:  pop2  
   74:  goto    181  
   77:  dup2  
   78:  arraylength  
   79:  swap  
   80:  arraylength  
   81:  if_icmpeq   88  
   84:  pop2  
   85:  goto    181  
   88:  astore_2  
   89:  astore_3  
   90:  iconst_0  
   91:  istore  4  
   93:  goto    134  
   96:  aload_2  
   97:  iload   4  
   99:  aaload  
   100: aload_3  
   101: iload   4  
   103: aaload  
   104: dup2  
   105: ifnonnull   115  
   108: ifnonnull   121  
   111: pop2  
   112: goto    131  
   115: ifnull  121  
   118: goto    125  
   121: pop2  
   122: goto    181  
   125: invokevirtual   #39; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z  
   128: ifeq    181  
   131: iinc    4, 1  
   134: iload   4  
   136: aload_2  
   137: arraylength  
   138: if_icmplt   96  
   141: aload_0  
   142: getfield    #27; //Field FIELD_2:Ljava/lang/String;  
   145: aload_1  
   146: checkcast   #2; //class net/sf/cglib/core/MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7  
   149: getfield    #27; //Field FIELD_2:Ljava/lang/String;  
   152: dup2  
   153: ifnonnull   163  
   156: ifnonnull   169  
   159: pop2  
   160: goto    179  
   163: ifnull  169  
   166: goto    173  
   169: pop2  
   170: goto    181  
   173: invokevirtual   #39; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z  
   176: ifeq    181  
   179: iconst_1  
   180: ireturn  
   181: iconst_0  
   182: ireturn  
  
public java.lang.String toString();  
  Code:  
   0:   new #43; //class java/lang/StringBuffer  
   3:   dup  
   4:   invokespecial   #44; //Method java/lang/StringBuffer."":()V  
   7:   aload_0  
   8:   getfield    #20; //Field FIELD_0:Ljava/lang/String;  
   11:  dup  
   12:  ifnull  24  
   15:  invokevirtual   #46; //Method java/lang/Object.toString:()Ljava/lang/String;  
   18:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
   21:  goto    30  
   24:  pop  
   25:  ldc #52; //String null  
   27:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
   30:  ldc #54; //String ,   
   32:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
   35:  aload_0  
   36:  getfield    #24; //Field FIELD_1:[Ljava/lang/String;  
   39:  dup  
   40:  ifnull  110  
   43:  swap  
   44:  ldc #56; //String {  
   46:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
   49:  swap  
   50:  astore_1  
   51:  iconst_0  
   52:  istore_2  
   53:  goto    86  
   56:  aload_1  
   57:  iload_2  
   58:  aaload  
   59:  dup  
   60:  ifnull  72  
   63:  invokevirtual   #46; //Method java/lang/Object.toString:()Ljava/lang/String;  
   66:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
   69:  goto    78  
   72:  pop  
   73:  ldc #52; //String null  
   75:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
   78:  ldc #54; //String ,   
   80:  invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
   83:  iinc    2, 1  
   86:  iload_2  
   87:  aload_1  
   88:  arraylength  
   89:  if_icmplt   56  
   92:  dup  
   93:  dup  
   94:  invokevirtual   #59; //Method java/lang/StringBuffer.length:()I  
   97:  iconst_2  
   98:  isub  
   99:  invokevirtual   #63; //Method java/lang/StringBuffer.setLength:(I)V  
   102: ldc #65; //String }  
   104: invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
   107: goto    116  
   110: pop  
   111: ldc #52; //String null  
   113: invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
   116: ldc #54; //String ,   
   118: invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
   121: aload_0  
   122: getfield    #27; //Field FIELD_2:Ljava/lang/String;  
   125: dup  
   126: ifnull  138  
   129: invokevirtual   #46; //Method java/lang/Object.toString:()Ljava/lang/String;  
   132: invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
   135: goto    144  
   138: pop  
   139: ldc #52; //String null  
   141: invokevirtual   #50; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;  
   144: invokevirtual   #66; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;  
   147: areturn  
  
}  


(3) JAVAASSIST動態代理接口生成的字節碼:

public class com.alibaba.test.performance.dynamicproxy.CountService_$$_javassist_0 extends java.lang.Object implements com.alibaba.test.performance.dynamicproxy.CountService,javassist.util.proxy.ProxyObject{  
public static javassist.util.proxy.MethodHandler default_interceptor;  
  
public static javassist.util.proxy.MethodFilter _method_filter;  
  
public com.alibaba.test.performance.dynamicproxy.CountService_$$_javassist_0();  
  Code:  
   0:   aload_0  
   1:   getstatic   #19; //Field default_interceptor:Ljavassist/util/proxy/MethodHandler;  
   4:   putfield    #21; //Field handler:Ljavassist/util/proxy/MethodHandler;  
   7:   getstatic   #23; //Field default_interceptor:Ljavassist/util/proxy/MethodHandler;  
   10:  ifnonnull   20  
   13:  aload_0  
   14:  getstatic   #27; //Field javassist/util/proxy/RuntimeSupport.default_interceptor:Ljavassist/util/proxy/MethodHandler;  
   17:  putfield    #29; //Field handler:Ljavassist/util/proxy/MethodHandler;  
   20:  aload_0  
   21:  invokespecial   #31; //Method java/lang/Object."":()V  
   24:  return  
  
public final boolean _d0equals(java.lang.Object);  
  Code:  
   0:   aload_0  
   1:   aload_1  
   2:   invokespecial   #38; //Method java/lang/Object.equals:(Ljava/lang/Object;)Z  
   5:   ireturn  
  
public final boolean equals(java.lang.Object);  
  Code:  
   0:   getstatic   #42; //Field _methods_:[Ljava/lang/reflect/Method;  
   3:   astore_2  
   4:   aload_0  
   5:   ldc #43; //String equals  
   7:   ldc #44; //String _d0equals  
   9:   iconst_0  
   10:  ldc #45; //String (Ljava/lang/Object;)Z  
   12:  aload_2  
   13:  invokestatic    #49; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V  
   16:  aload_0  
   17:  getfield    #51; //Field handler:Ljavassist/util/proxy/MethodHandler;  
   20:  aload_0  
   21:  aload_2  
   22:  iconst_0  
   23:  aaload  
   24:  aload_2  
   25:  iconst_1  
   26:  aaload  
   27:  iconst_1  
   28:  anewarray   #52; //class java/lang/Object  
   31:  dup  
   32:  iconst_0  
   33:  aload_1  
   34:  aastore  
   35:  invokeinterface #58,  5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
   40:  checkcast   #60; //class java/lang/Boolean  
   43:  invokevirtual   #64; //Method java/lang/Boolean.booleanValue:()Z  
   46:  ireturn  
  
public final java.lang.Object _d1clone()   throws java.lang.CloneNotSupportedException;  
  Code:  
   0:   aload_0  
   1:   invokespecial   #72; //Method java/lang/Object.clone:()Ljava/lang/Object;  
   4:   areturn  
  
protected final java.lang.Object clone()   throws java.lang.CloneNotSupportedException;  
  Code:  
   0:   getstatic   #74; //Field _methods_:[Ljava/lang/reflect/Method;  
   3:   astore_1  
   4:   aload_0  
   5:   ldc #75; //String clone  
   7:   ldc #76; //String _d1clone  
   9:   iconst_2  
   10:  ldc #77; //String ()Ljava/lang/Object;  
   12:  aload_1  
   13:  invokestatic    #79; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V  
   16:  aload_0  
   17:  getfield    #81; //Field handler:Ljavassist/util/proxy/MethodHandler;  
   20:  aload_0  
   21:  aload_1  
   22:  iconst_2  
   23:  aaload  
   24:  aload_1  
   25:  iconst_3  
   26:  aaload  
   27:  iconst_0  
   28:  anewarray   #52; //class java/lang/Object  
   31:  invokeinterface #83,  5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
   36:  checkcast   #4; //class java/lang/Object  
   39:  areturn  
  
public final int _d2hashCode();  
  Code:  
   0:   aload_0  
   1:   invokespecial   #88; //Method java/lang/Object.hashCode:()I  
   4:   ireturn  
  
public final int hashCode();  
  Code:  
   0:   getstatic   #90; //Field _methods_:[Ljava/lang/reflect/Method;  
   3:   astore_1  
   4:   aload_0  
   5:   ldc #91; //String hashCode  
   7:   ldc #92; //String _d2hashCode  
   9:   iconst_4  
   10:  ldc #93; //String ()I  
   12:  aload_1  
   13:  invokestatic    #95; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V  
   16:  aload_0  
   17:  getfield    #97; //Field handler:Ljavassist/util/proxy/MethodHandler;  
   20:  aload_0  
   21:  aload_1  
   22:  iconst_4  
   23:  aaload  
   24:  aload_1  
   25:  iconst_5  
   26:  aaload  
   27:  iconst_0  
   28:  anewarray   #52; //class java/lang/Object  
   31:  invokeinterface #99,  5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
   36:  checkcast   #101; //class java/lang/Integer  
   39:  invokevirtual   #104; //Method java/lang/Integer.intValue:()I  
   42:  ireturn  
  
public final int count();  
  Code:  
   0:   getstatic   #107; //Field _methods_:[Ljava/lang/reflect/Method;  
   3:   astore_1  
   4:   aload_0  
   5:   ldc #108; //String count  
   7:   aconst_null  
   8:   bipush  6  
   10:  ldc #109; //String ()I  
   12:  aload_1  
   13:  invokestatic    #111; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V  
   16:  aload_0  
   17:  getfield    #113; //Field handler:Ljavassist/util/proxy/MethodHandler;  
   20:  aload_0  
   21:  aload_1  
   22:  bipush  6  
   24:  aaload  
   25:  aload_1  
   26:  bipush  7  
   28:  aaload  
   29:  iconst_0  
   30:  anewarray   #52; //class java/lang/Object  
   33:  invokeinterface #115,  5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
   38:  checkcast   #101; //class java/lang/Integer  
   41:  invokevirtual   #117; //Method java/lang/Integer.intValue:()I  
   44:  ireturn  
  
public final void _d4finalize()   throws java.lang.Throwable;  
  Code:  
   0:   aload_0  
   1:   invokespecial   #123; //Method java/lang/Object.finalize:()V  
   4:   return  
  
protected final void finalize()   throws java.lang.Throwable;  
  Code:  
   0:   getstatic   #125; //Field _methods_:[Ljava/lang/reflect/Method;  
   3:   astore_1  
   4:   aload_0  
   5:   ldc #126; //String finalize  
   7:   ldc #127; //String _d4finalize  
   9:   bipush  8  
   11:  ldc #128; //String ()V  
   13:  aload_1  
   14:  invokestatic    #130; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V  
   17:  aload_0  
   18:  getfield    #132; //Field handler:Ljavassist/util/proxy/MethodHandler;  
   21:  aload_0  
   22:  aload_1  
   23:  bipush  8  
   25:  aaload  
   26:  aload_1  
   27:  bipush  9  
   29:  aaload  
   30:  iconst_0  
   31:  anewarray   #52; //class java/lang/Object  
   34:  invokeinterface #134,  5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
   39:  pop  
   40:  return  
  
public final java.lang.String _d5toString();  
  Code:  
   0:   aload_0  
   1:   invokespecial   #139; //Method java/lang/Object.toString:()Ljava/lang/String;  
   4:   areturn  
  
public final java.lang.String toString();  
  Code:  
   0:   getstatic   #141; //Field _methods_:[Ljava/lang/reflect/Method;  
   3:   astore_1  
   4:   aload_0  
   5:   ldc #142; //String toString  
   7:   ldc #143; //String _d5toString  
   9:   bipush  10  
   11:  ldc #144; //String ()Ljava/lang/String;  
   13:  aload_1  
   14:  invokestatic    #146; //Method javassist/util/proxy/RuntimeSupport.find2Methods:(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/reflect/Method;)V  
   17:  aload_0  
   18:  getfield    #148; //Field handler:Ljavassist/util/proxy/MethodHandler;  
   21:  aload_0  
   22:  aload_1  
   23:  bipush  10  
   25:  aaload  
   26:  aload_1  
   27:  bipush  11  
   29:  aaload  
   30:  iconst_0  
   31:  anewarray   #52; //class java/lang/Object  
   34:  invokeinterface #150,  5; //InterfaceMethod javassist/util/proxy/MethodHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;  
   39:  checkcast   #152; //class java/lang/String  
   42:  areturn  
  
static {};  
  Code:  
   0:   bipush  12  
   2:   anewarray   #155; //class java/lang/reflect/Method  
   5:   putstatic   #157; //Field _methods_:[Ljava/lang/reflect/Method;  
   8:   return  
  
public void setHandler(javassist.util.proxy.MethodHandler);  
  Code:  
   0:   aload_0  
   1:   aload_1  
   2:   putfield    #161; //Field handler:Ljavassist/util/proxy/MethodHandler;  
   5:   return  
  
java.lang.Object writeReplace()   throws java.io.ObjectStreamException;  
  Code:  
   0:   aload_0  
   1:   invokestatic    #168; //Method javassist/util/proxy/RuntimeSupport.makeSerializedProxy:(Ljava/lang/Object;)Ljavassist/util/proxy/SerializedProxy;  
   4:   areturn  
  
}  

(5) JAVAASSIST拼接源碼生成的字節碼: 

public class com.alibaba.test.performance.dynamicproxy.CountServiceJavaassistProxy extends java.lang.Object implements com.alibaba.test.performance.dynamicproxy.CountService{  
public com.alibaba.test.performance.dynamicproxy.CountService delegate;  
  
public com.alibaba.test.performance.dynamicproxy.CountServiceJavaassistProxy();  
  Code:  
   0:   aload_0  
   1:   invokespecial   #12; //Method java/lang/Object."":()V  
   4:   return  
  
public int count();  
  Code:  
   0:   aload_0  
   1:   getfield    #19; //Field delegate:Lcom/alibaba/test/performance/dynamicproxy/CountService;  
   4:   invokeinterface #21,  1; //InterfaceMethod com/alibaba/test/performance/dynamicproxy/CountService.count:()I  
   9:   ireturn  
  
}  

(6) 用ASM自行生成的字節碼: 

public class com.alibaba.test.performance.dynamicproxy.CountServiceAsmProxy extends java.lang.Object implements com.alibaba.test.performance.dynamicproxy.CountService{  
public com.alibaba.test.performance.dynamicproxy.CountService delegate;  
  
public com.alibaba.test.performance.dynamicproxy.CountServiceAsmProxy();  
  Code:  
   0:   aload_0  
   1:   invokespecial   #10; //Method java/lang/Object."":()V  
   4:   return  
  
public int count();  
  Code:  
   0:   aload_0  
   1:   getfield    #16; //Field delegate:Lcom/alibaba/test/performance/dynamicproxy/CountService;  
   4:   invokeinterface #18,  1; //InterfaceMethod com/alibaba/test/performance/dynamicproxy/CountService.count:()I  
   9:   ireturn  
  
}  

附上本人的測試結果:

JDK1.8  ASM-6.2.1  CGLIB-3.2.8  JAVAASSIST-3.23.1-GA

運行環境:PC機 4Cores CPU()

Create JDK Proxy: 20 ms

Create CGLIB Proxy: 236 ms

Create JAVAASSIST Proxy: 315 ms

Create JAVAASSIST Bytecode Proxy: 181 ms

Create ASM Proxy: 2 ms

================

Run JDK Proxy: 201 ms, 7,015,250 t/s

Run CGLIB Proxy: 219 ms, 6,438,654 t/s

Run JAVAASSIST Proxy: 461 ms, 3,058,710 t/s

Run JAVAASSIST Bytecode Proxy: 146 ms, 9,657,982 t/s

Run ASM Bytecode Proxy: 111 ms, 12,703,291 t/s

----------------

Run JDK Proxy: 285 ms, 4,947,597 t/s

Run CGLIB Proxy: 128 ms, 11,016,136 t/s

Run JAVAASSIST Proxy: 403 ms, 3,498,921 t/s

Run JAVAASSIST Bytecode Proxy: 80 ms, 17,625,817 t/s

Run ASM Bytecode Proxy: 88 ms, 16,023,470 t/s

----------------

Run JDK Proxy: 191 ms, 7,382,541 t/s

Run CGLIB Proxy: 162 ms, 8,704,107 t/s

Run JAVAASSIST Proxy: 357 ms, 3,949,763 t/s

Run JAVAASSIST Bytecode Proxy: 106 ms, 13,302,503 t/s

Run ASM Bytecode Proxy: 80 ms, 17,625,817 t/s

----------------

便捷性比較

排序(只是生成字節碼,語義性):javassist>asm

排序(動態代理):cglib=jdk>javassist bytecode>javassist proxy>asm

個人感覺通過javassist bytecode方式比較好,也是採用的字節碼方式,並且相比asm更加容易理解,效率和asm對比不相上下。但是實現的代碼量可能會比較冗長,還要看使用者所關注的是什麼。

---------------------------------------------------------------------------------------------------------------------------------

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章