dubbo动态代理javassist和jdk区别:
生成动态代理类:都可以根据字节码生成class文件,JAVAASSIST既可以通过动态代理也可以通过字节码生成class文件
执行代理类的方法,javassist更快
package proxySpeed;
/**
* @Author: zhangshaolong001
* @Date: 2019/12/3 8:19 PM
* @Description:
*/
public interface CountService {
int count();
}
package proxySpeed;
/**
* @Author: zhangshaolong001
* @Date: 2019/12/3 8:19 PM
* @Description:
*/
public class CountServiceImpl implements CountService {
private int count = 0;
@Override
public int count() {
return count ++;
}
}
package proxySpeed;
import javassist.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.text.DecimalFormat;
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 javassistBytecodeProxy = createJavassistBytecodeDynamicProxy(delegate);
time = System.currentTimeMillis() - time;
System.out.println("Create JAVAASSIST Bytecode Proxy: " + time + " ms");
for (int i = 0; i < 3; i++) {
test(jdkProxy, "Run JDK Proxy: ");
test(javassistBytecodeProxy, "Run JAVAASSIST Bytecode Proxy: ");
System.out.println("----------------");
}
}
private static void test(CountService service, String label)
throws Exception {
service.count(); // warm up
int count = 100000000;
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;
}
@Override
public Object invoke(Object object, Method method, Object[] objects)
throws Throwable {
return method.invoke(delegate, objects);
}
}
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;
}
}
jdk1.8.0_121,macbook pro 4核:
Create JDK Proxy: 7 ms
Create JAVAASSIST Bytecode Proxy: 190 ms
Run JDK Proxy: 306 ms, 3,973,046 t/s
Run JAVAASSIST Bytecode Proxy: 86 ms, 14,136,653 t/s
----------------
Run JDK Proxy: 361 ms, 3,367,734 t/s
Run JAVAASSIST Bytecode Proxy: 3 ms, 405,250,730 t/s
----------------
Run JDK Proxy: 286 ms, 4,250,881 t/s
Run JAVAASSIST Bytecode Proxy: 4 ms, 303,938,048 t/s
----------------
(每个类只需要生成一次,但可能执行无数次)
创建代理类,jdk更快
执行代理类的方法,javassist更快,执行多次就可以显著提升性能
参考dubbo作者博客:https://www.iteye.com/blog/javatar-814426