美文网首页
java动态代理

java动态代理

作者: 7d972d5e05e8 | 来源:发表于2020-03-13 11:02 被阅读0次

一、 dubbo的SPI代理和Invoker的代理

入口:createAdaptiveExtensionClass -> CtClass.toClass
入口:Proxy getProx -> ClassGenerator.toClass -> CtClass.toClass

二、JDK动态代理效率比Cglib动态代理低的原因

JDK动态代理,方法调用的核心如下:

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);
        }
    }

该invoke方法的核心是使用method.invoke进行反射调用,方法调用并没有直接去类的方法表去搜索。
而Cglib动态代理,方法调用核心如下:

private static class CglibInterceptor implements MethodInterceptor {

        final Object delegate;

        CglibInterceptor(Object delegate) {
            this.delegate = delegate;
        }

        @Override
        public Object intercept(Object object, Method method, Object[] objects,
                MethodProxy methodProxy) throws Throwable {
            return methodProxy.invoke(delegate, objects);
        }
    }

该invoke方法的核心是使用MethodProxy.invoke进行调用,而非反射调用。methodProxy的调用为啥会快于反射调用呢。是因为cglib为被代理类也生成了代理类,然后通过fastClass机制调用。性能可以比肩对象直接调用,稍微有些性能损失,但是要强于反射调用。

fastClass的invoke方法是抽象方法,无法在cglib的源码中找到实现类。为啥呢?因为fastClass是和业务类紧密关联的,cglib没法知道业务类有哪些,只能在运行的时候,通过init里面的helper()方法动态生成fastClass。这个fastClass运行期间,只生成一次,后面再获取可以直接从缓存中拿。而fastClass经过反编译,可以看到源码。

什么是fastClass机制呢?

参考文档:https://blog.csdn.net/yzb808/article/details/88641156

FastClass的实现逻辑,是生成增强类实现invoke方法,invoke方法中,用switch语义将被增强类的所有方法调用枚举出来。用户使用FastClass.invoke方法,传入方法签名和被调用实例,从而达到不使用反射就能实现不确定方法的调用。

FastClass是否真的能比反射调用速度快吗?

参考文档:https://blog.csdn.net/yzb808/article/details/88641156

测试代码如上面的文档中,暂时就不贴了。从测试结果上看,一千万次调用的总耗时,默认情况下,反射执行效率明显优于FastClass。反射操作的时间开销主要存在于获取被反射的方法信息上,默认情况下使用JNI访问器获得该信息。但高版本的JVM在执行反射时引入通胀概念,也即参数-Dsun.reflect.inflationThreshold(默认15)。当一段反射逻辑执行次数超过阈值后,会生成被反射类对应的字节码访问器(sun/reflect/GeneratedMethodAccessor和sun/reflect/DelegatingClassLoader),用于加快反射调用。测试代码中提高通胀阈值后发现反射的执行效率变得很差。

使用FastClass或反射生成字节码访问器都会构造新类占用perm区,网上看到一些oom的例子。但从执行效率方面考量,反射性能更好。
————————————————
学习了!

相关文章

  • Java 动态代理

    java的动态代理机制详解 JDK动态代理详解 Java核心技术点之动态代理

  • JDK动态代理详解

    JDK动态代理详解 java动态代理类 Java动态代理类位于java.lang.reflect包下,一般主要涉及...

  • Java动态代理从入门到原理再到实战

    目录 前言 什么是动态代理,和静态代理有什么区别 Java动态代理的简单使用 Java动态代理的原理解读 动态代理...

  • java反射和动态代理

    java动态代理Proxy.newProxyInstance 详解java代理机制(静态代理、动态代理)以及使用场景

  • 保存java 动态代理生成的字节码文件

    保存java 动态代理生成的字节码文件 在Java中,常用的动态代理技术有JDK的动态代理和cglib动态代理,不...

  • java动态代理(JDK和cglib)(转载自http://ww

    java动态代理(JDK和cglib) JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是...

  • java基础巩固笔记(4)-代理

    标签: java Contents java基础巩固笔记(4)-代理概念动态代理创建动态类动态代理的工作原理面向切...

  • java 动态代理

    动态代理动态代理可以让我们在运行时动态生成代理类,解耦程度更高。Java 动态代理的实现主要借助于 java.la...

  • java随笔(十一)

    java动态代理源码分析,总结。java动态代理实现步骤: 通过阅读源码发现,动态生成代理对象$Proxy0,该对...

  • Java基础:反射

    反射注解动态代理相关阅读 Java基础:类加载器 Java基础:反射 Java基础:注解 Java基础:动态代理 ...

网友评论

      本文标题:java动态代理

      本文链接:https://www.haomeiwen.com/subject/amwpactx.html