文档章节

Java 动态代理的实现

我爱春天的毛毛雨
 我爱春天的毛毛雨
发布于 11/14 10:47
字数 6044
阅读 9
收藏 0

在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对比不相上下。但是实现的代码量可能会比较冗长,还要看使用者所关注的是什么。

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

© 著作权归作者所有

共有 人打赏支持
我爱春天的毛毛雨
粉丝 3
博文 44
码字总数 102873
作品 0
鸡西
私信 提问
java动态代理(JDK和cglib)

JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代...

长平狐
2012/10/09
272
0
咕泡-代理 proxy 设计模式笔记

##查看代码:https://gitee.com/jly521/proxy.git 代理模式(Proxy) 应用场景:为其他对象提供一种代理以控制对这个对象的访问 从结构上来看和Decorator 模式类似, 但Proxy 是控制,更像是...

职业搬砖20年
08/22
0
0
动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

在运行时期可以按照Java虚拟机规范对class文件的组织规则生成对应的二进制字节码。当前有很多开源框架可以完成这些功能,如ASM,Javassist。 动态代理机制详解(JDK 和CGLIB,Javassist,ASM...

素雷
2017/10/19
0
0
Java代理-Javassist

代理 (agent) 是在你的main方法前的一个拦截器 (interceptor),也就是在main方法执行之前,执行agent的代码。agent的代码与你的main方法在同一个JVM中运行,并被同一个system classloader装载...

ksfzhaohui
2014/09/02
0
0
Java程序员从笨鸟到菜鸟之(三十九)大话设计模式(七)代理模式和java动态代理机制

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188 代理设计模式 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类...

长平狐
2012/11/12
197
0

没有更多内容

加载失败,请刷新页面

加载更多

ubuntu美化记,-修改皮肤,安装工具。

事情由来 最近系统盘坏了,换了新SSD,也换了新版的ubuntu 18.04LTS;不得不说,ubuntu 的桌面搞的越来越漂亮了。 把调整过的zsh shell样式,截个图上来镇一下楼: 添加了对python virtuale...

janl
3分钟前
0
0
阿里云物联网边缘计算加载MQTT驱动

写在前面 本文在LinkEdge快速入门样例驱动的基础上,加载了MQTT订阅的客户端,使得边缘端容器可以通过MQTT获得外部数据。 1. 系统需求 物联网边缘计算平台,又名Link IoT Edge[1]。在物联网边...

阿里云云栖社区
4分钟前
0
0
错误: 找不到或无法加载主类

在IDEA的使用过程中,经常断掉服务或者重启服务,最近断掉服务重启时突然遇到了一个启动报错: 错误:找不到或无法加载主类 猜测:1,未能成功编译; 尝试:菜单---》Build---》Rebuild Pro...

安小乐
20分钟前
1
0
vue路由传参,刷新页面,引发的bug

最近遇到一个bug 通过vue路由跳转到页面, 然后接参控制(v-if ),成功显示 而刷新页面,显示失败。 苦苦地找了半天原因,打印参数发现正确,再打印下类型......,路由跳过来会保持传参时的...

hanbb
21分钟前
1
0
【58沈剑 架构师之路】InnoDB,select为啥会阻塞insert?

MySQL的InnoDB的细粒度行锁,是它最吸引人的特性之一。 但是,如《InnoDB,5项最佳实践》所述,如果查询没有命中索引,也将退化为表锁。 InnoDB的细粒度锁,是实现在索引记录上的。 一,Inn...

张锦飞
24分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部