dubbo选javassist作为缺省动态代理原因

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

你可能感兴趣的:(dubbo原理)