动态代理方案性能对比 (CGLIB,ASSIT,JDK)

动态代理工具比较成熟的产品有: 
JDK自带的,ASMCGLIB(基于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) 

Java代码  

  1. Create JDK Proxy: 13 ms  
  2. Create CGLIB Proxy: 217 ms  
  3. Create JAVAASSIST Proxy: 99 ms  
  4. Create JAVAASSIST Bytecode Proxy: 168 ms  
  5. Create ASM Proxy: 3 ms  
  6. ================  
  7. Run JDK Proxy: 2224 ms, 634,022 t/s  
  8. Run CGLIB Proxy: 1123 ms, 1,255,623 t/s  
  9. Run JAVAASSIST Proxy: 3212 ms, 438,999 t/s  
  10. Run JAVAASSIST Bytecode Proxy: 206 ms, 6,844,977 t/s  
  11. Run ASM Bytecode Proxy: 209 ms, 6,746,724 t/s  
  12. ----------------  
  13. Run JDK Proxy: 2169 ms, 650,099 t/s  
  14. Run CGLIB Proxy: 1059 ms, 1,331,506 t/s  
  15. Run JAVAASSIST Proxy: 3328 ms, 423,697 t/s  
  16. Run JAVAASSIST Bytecode Proxy: 202 ms, 6,980,521 t/s  
  17. Run ASM Bytecode Proxy: 206 ms, 6,844,977 t/s  
  18. ----------------  
  19. Run JDK Proxy: 2174 ms, 648,604 t/s  
  20. Run CGLIB Proxy: 1032 ms, 1,366,342 t/s  
  21. Run JAVAASSIST Proxy: 3119 ms, 452,088 t/s  
  22. Run JAVAASSIST Bytecode Proxy: 207 ms, 6,811,910 t/s  
  23. Run ASM Bytecode Proxy: 207 ms, 6,811,910 t/s  
  24. ----------------  



(2) 服务器测试结果:Linux 2.6.18-128.el5xen(64bit), 16 Cores CPU(Intel Xeon E5520 2.27GHz) 

Java代码  

  1. Create JDK Proxy: 7 ms  
  2. Create CGLIB Proxy: 86 ms  
  3. Create JAVAASSIST Proxy: 36 ms  
  4. Create JAVAASSIST Bytecode Proxy: 57 ms  
  5. Create ASM Proxy: 1 ms  
  6. ================  
  7. Run JDK Proxy: 235 ms, 6,000,278 t/s  
  8. Run CGLIB Proxy: 234 ms, 6,025,920 t/s  
  9. Run JAVAASSIST Proxy: 459 ms, 3,072,037 t/s  
  10. Run JAVAASSIST Bytecode Proxy: 71 ms, 19,860,076 t/s  
  11. Run ASM Bytecode Proxy: 72 ms, 19,584,241 t/s  
  12. ----------------  
  13. Run JDK Proxy: 298 ms, 4,731,763 t/s  
  14. Run CGLIB Proxy: 134 ms, 10,522,876 t/s  
  15. Run JAVAASSIST Proxy: 406 ms, 3,473,067 t/s  
  16. Run JAVAASSIST Bytecode Proxy: 67 ms, 21,045,752 t/s  
  17. Run ASM Bytecode Proxy: 66 ms, 21,364,627 t/s  
  18. ----------------  
  19. Run JDK Proxy: 282 ms, 5,000,231 t/s  
  20. Run CGLIB Proxy: 133 ms, 10,601,995 t/s  
  21. Run JAVAASSIST Proxy: 406 ms, 3,473,067 t/s  
  22. Run JAVAASSIST Bytecode Proxy: 67 ms, 21,045,752 t/s  
  23. Run ASM Bytecode Proxy: 67 ms, 21,045,752 t/s  
  24. ----------------  



(测试结论: 
1. ASMJAVAASSIST字节码生成方式不相上下,都很快,是CGLIB5倍。 
2. CGLIB次之,是JDK自带的两倍。 
3. JDK自带的再次之,因JDK1.6对动态代理做了优化,如果用低版本JDK更慢,要注意的是JDK也是通过字节码生成来实现动态代理的,而不是反射。 
4. JAVAASSIST提供者动态代理接口最慢,比JDK自带的还慢。 
(这也是为什么网上有人说JAVAASSISTJDK还慢的原因,用JAVAASSIST最好别用它提供的动态代理接口,而可以考虑用它的字节码生成方式

(差异原因: 
各方案生成的字节码不一样, 
JDKCGLIB都考虑了很多因素,以及继承或包装了自己的一些类, 
所以生成的字节码非常大,而我们很多时候用不上这些, 
而手工生成的字节码非常小,所以速度快, 
具体的字节码对比,后面有贴出,可自行分析。 

(最终选型: 
最终决定使用JAVAASSIST的字节码生成代理方式, 
虽然ASM稍快,但并没有快一个数量级, 
JAVAASSIST的字节码生成方式比ASM方便, 
JAVAASSIST只需用字符串拼接出Java源码,便可生成相应字节码, 
ASM需要手工写字节码。 

(测试代码: 

Java代码  

public interface CountService {
    int count();
}

Java代码  

public class CountServiceImpl implements CountService {

    private int count = 0;
    
    public int count() {
        return count++;
    }
}

Java代码  

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生成的字节码: 

Java代码  

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生成的字节码: 

Java代码  

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动态代理接口生成的字节码: 

Java代码  

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拼接源码生成的字节码: 

Java代码  

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自行生成的字节码: 

Java代码  

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  

  }  

原文地址:https://www.cnblogs.com/yangmengdx3/p/4493309.html