好记性不如烂笔头48-java拦截器-JDK自带动态代理和CGLIB效率比较(3)

Java中自带的动态代理的类必须要实现一个接口,而且据说使用反射的效率也并不是很高。于是CGLIB就诞生了。

使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,理论上比使用Java反射效率要高。

那么我们测试下,这个运行的效率如何。

1、 测试的准备情况

准备1:好记性不如烂笔头46-java拦截器-彻底理解动态代理的概念(1) http://blog.csdn.net/ffm83/article/details/43699619

准备2: 好记性不如烂笔头47-java拦截器-用CGLib实现动态代理(2)

http://blog.csdn.net/ffm83/article/details/43702321

为了测试结果方便观察,把所有的打印输出关闭。

JDK版本: jdk1.6.0_25

2、 测试运行效率的源代码

package com.tools;

import com.CGLib.WangBaoQiang;
import com.proxy.Actor;
/**
 * 使用预热模式
 * JVM参数:-XX:PrintCompilation
 * @author 范芳铭
 */
public class BaseRun_Proxy_Test {
    public static void main(String[] args) throws Exception{
        int warmUpCycles = 1000000; //预热次数
        BaseRun_Proxy_Test se = new BaseRun_Proxy_Test();
        System.out.println("预热循环开始 ...");
        se.runTest(warmUpCycles);
        System.out.println("预热结束");

        Thread.sleep(1000); //让系统暂停

        System.out.println("进入正式循环 ...");
        se.runTest(1);
        se.runTest(100);
        se.runTest(10000);
        se.runTest(1000000);
        se.runTest(20000000); //2000千万次,我们系统一天的访问量
        System.out.println("正式运算完成");
    }

    private void runTest(int iterations){
        BaseRun_Proxy_Test lot = new BaseRun_Proxy_Test();
        //运行JAVA自带动态代理
        long startTime = System.nanoTime();
        for(int i = 0 ; i < iterations ;  i ++){
            lot.getJavaProxyLoop();
        }
        long elapsedTime = System.nanoTime();
        System.out.println("运行JAVA自带动态代理:" + iterations + ",结束,耗时:" + (elapsedTime-startTime));
        //运行CGLIB
        long cglibStartTime = System.nanoTime();
        for(int i = 0 ; i < iterations ;  i ++){
            lot.getCGLibLoop();
        }
        long cglibElapsedTime = System.nanoTime();
        System.out.println("运行CGLIB动态代理:" + iterations + ",结束,耗时:" + (cglibElapsedTime-cglibStartTime));
    }

    public void getJavaProxyLoop(){
        // 首先找到经纪人
        com.proxy.ActorJingJiRen proxy = new com.proxy.ActorJingJiRen();
        // 通过经纪人获得相关演员(代理对象)
        Actor p = proxy.getProxy();
        String retValue = p.sing("天下无贼");
        String value = p.dance("凤凰传奇");
    }

    public void getCGLibLoop(){
        com.CGLib.ActorJingJiRen proxy = new com.CGLib.ActorJingJiRen();
        // 通过经纪人获得相关演员(代理对象)
        WangBaoQiang p = proxy.getProxy();
        String retValue = p.sing("天下无贼");
        String value = p.dance("凤凰传奇");
    }
}

3、 运行结果

预热循环开始 …

运行JAVA自带动态代理:1000000,结束,耗时:2390557348

运行CGLIB动态代理:1000000,结束,耗时:6111703990

预热结束

进入正式循环 …

运行JAVA自带动态代理:1,结束,耗时:35715

运行CGLIB动态代理:1,结束,耗时:39409

运行JAVA自带动态代理:100,结束,耗时:381782

运行CGLIB动态代理:100,结束,耗时:1162997

运行JAVA自带动态代理:10000,结束,耗时:23943050

运行CGLIB动态代理:10000,结束,耗时:58153974

运行JAVA自带动态代理:1000000,结束,耗时:2403822826

运行CGLIB动态代理:1000000,结束,耗时:5804202226

运行JAVA自带动态代理:20000000,结束,耗时:48913882774

运行CGLIB动态代理:20000000,结束,耗时:118967606438

正式运算完成

4、 运行效率的表格

CGlib的动态代理的效率,看起来比JAVA自带的效率要低。这个和我们所听到的情况可能不一样。

5、 其他

将CGLIB放在java自带proxy的方法之前,数据情况和上面基本一致。

时间: 2024-10-03 04:39:38

好记性不如烂笔头48-java拦截器-JDK自带动态代理和CGLIB效率比较(3)的相关文章

JDK动态代理和CGLIB代理的区别

一.原理区别: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. 而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理. 1.如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2.如果目标对象实现了接口,可以强制使用CGLIB实现AOP 3.如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换 如何强制使用

JDK动态代理和CGLIB动态代理

转载自http://www.itzhai.com/java-dong-tai-dai-li-zhi-jdk-dong-tai-dai-li-he-cglib-dong-tai-dai-li-mian-xiang-qie-mian-bian-cheng-aop-yuan-li.html 静态代理 静态代理相对来说比较简单,无非就是聚合+多态: 参考:设计模式笔记 – Proxy 代理模式 (Design Pattern) 动态代理 我们知道,通过使用代理,可以在被代理的类的方法的前后添加一些处理方

spring aop原理 JDK动态代理和CGLIB动态代理

Spring的两大特性是IOC和AOPIOC负责将对象动态的注入到容器,从而达到一种需要谁就注入谁,什么时候需要就什么时候注入的效果.理解spring的ioc也很重要.但是今天主要来和大家讲讲aop.AOP 广泛应用于处理一些具有横切性质的系统级服务,AOP 的出现是对 OOP 的良好补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理.日志.缓存等等. AOP实现的关键在于AOP框架自动创建的AOP代理.AOP代理主要分为静态代理和动态代理, 静态代理的代表为AspectJ:动态代理则

设计模式---JDK动态代理和CGLIB代理

Cglig代理设计模式 /*测试类*/ package cglibProxy; import org.junit.Test; public class TestCglib { @Test public void test1(){ CglibProxy cglibProxy=new CglibProxy(); UserServiceImpl userServiceImpl = (UserServiceImpl)cglibProxy.createProxyInstance(new UserServi

jdk动态代理和cglib动态代理底层实现原理详细解析(cglib动态代理篇)

代理模式是一种很常见的模式,关于底层原理网上看到很多的有关的讲解,但看了一些都觉得比较粗略,很多时候把底层代码copy下来也不大讲解,感觉不如自己详细的写上一篇.本文将以非常详细的说明来分析cglib动态代理底层的实现原理,篇幅较长,但是每个核心方法代码中每步都有说明.还请耐心阅读 1. 举例 使用cglib代理需要引入两个包,maven的话包引入如下 <!-- https://mvnrepository.com/artifact/cglib/cglib --> <dependency&

JDK动态代理和CGLIB动态代理+源码下载

在上一篇文章-java代理详解讲解实现机制,一种是继承另外一种是组合,而且通过做实现也证明使用组合的方式更加的灵活.之后提到了代理的两种种类,一种是静态代理,另外一种是动态代理.上一篇文件中着重介绍的是静态代理(相对于动态代理很容易理解).这一片文章就接着介绍动态代理. 动态代理实现的最终效果:通过以一个统一的方式实现对任意的接口/类的代理.相比较静态代理而言,我们可以不用再无限制的增加代理类,不用再写许多重复的代码.很符合面向对象设计原则中的"开闭原则":对修改关闭,对扩展开放. 动

关于JDK动态代理和CGLIB动态代理

1. 代理模式 一句话总结:为其他对象提供一种代理以控制对这个对象的访问.千篇一律的介绍:代理模式是常用的java设计模式,他的特征是代理类与委托类(或目标类)有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. 按照代理的创建时期,代理类可以分为两种. 静态代理:由程序员创建或特定工具

JDK动态代理和Cglib的动态代理

最简单的是静态代理方法,即代理模式,这里就不多啰嗦了.. 重点说一下JDK的动态代理和Cglib的动态代理吧 先说JDK的,需要被代理的类需要有接口,否则无法实现 package proxy.dynamic; public interface IBook { void add(); } 实现接口的类如下 package proxy.dynamic; public class Book implements IBook { @Override public void add() { System.

【Spring】AOP之JDK动态代理和CGLib动态代理

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一.JAVA动态代理  1.1 代理模式         代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. 按照代理的创