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

本文对比了Dubbo中使用Javassist和JDK进行动态代理的性能差异。实验结果显示,在创建代理类时,JDK代理表现更快;但在执行代理类方法时,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

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值