转于自己在公司的Blog:
http://pt.alibaba-inc.com/wp/experience_1054/dynamic_proxy_performance.html
因服务框架需要用动态代理生成客户端接口的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
}