态代理方案性能对比(转)

2018-06-10  本文已影响0人  西华子

因服务框架需要用动态代理生成客户端接口的stub,所以做了一下性能评测,
动态代理工具比较成熟的产品有:
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  
  
}  
上一篇下一篇

猜你喜欢

热点阅读