先在mavne项目里添加cglib库

maven仓库搜索cglib版本

maven地址:http://mvnrepository.com/

点击最新的版本 3.2.5

复制到pom.xml  dependencies 标签下

  1. <dependency>
  2. <groupId>cglib</groupId>
  3. <artifactId>cglib</artifactId>
  4. <version>3.2.5</version>
  5. </dependency>

接着在TestProxy.class添加方法

  1. public static void testCglib() {
  2. Enhancer enhancer = new Enhancer();
  3. enhancer.setSuperclass(UserServiceImpl.class);
  4. enhancer.setCallback(new MethodInterceptor() {
  5.  
  6. @Override
  7. public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
  8. return proxy.invokeSuper(obj, args);
  9.  
  10. }
  11. });
  12. UserService impTarget = (UserService) enhancer.create();
  13. run("cglib",impTarget);
  14. }
  1. public static void main(String[] args) {
  2. testNative();
  3. testJdk();
  4. testCglib();
  5. }

继续运行测试:

native: 177 native: 191 native: 132 native: 179 native: 132 native: 152 native: 183 native: 131 native: 133 native: 132 native: 131 native: 133 native: 132 native: 132 native: 133
jdk: 218 jdk: 172 jdk: 172 jdk: 173 jdk: 172 jdk: 172 jdk: 172 jdk: 172 jdk: 173 jdk: 172 jdk: 174 jdk: 172 jdk: 172 jdk: 172 jdk: 173
cglib: 294 cglib: 271 cglib: 271 cglib: 284 cglib: 270 cglib: 270 cglib: 268 cglib: 268 cglib: 269 cglib: 268 cglib: 269 cglib: 269 cglib: 280 cglib: 268 cglib: 273

可以看出 cglib比jdk还要慢

我们来查看下生成的class指令有多少条

先加一行System.in.read();  防止程序退出

  1. public static void main(String[] args) throws IOException {
  2. testNative();
  3. testJdk();
  4. testCglib();
  5. System.in.read();
  6. }

运行HSDB工具

1)、打开cmd窗口,运行命令:java -classpath "%JAVA_HOME%/lib/sa-jdi.jar" sun.jvm.hotspot.HSDB

2)、点击file菜单下第一项


弹出

3)、打开任务管理器,在任务管理器菜单查看->选择列->勾选PID

找到当前运行java程序的进程号pid,输入到上图的文本框中,点击ok弹出

4)、点击工具(tools)菜单下的第一项Class Browser。弹出

5)、输入包名TestProxy回车.只要看cglib生成的动态类

只要看 super class 实现类

6)、点击Create .class File,在HSDB工具运行目录下下生产cglib动态代理类

用jd-gui打开

逻辑跟JDK差不多,只要不同部分

  1. public final String getName(int paramInt)
  2. {
  3. MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
  4. if (tmp4_1 == null)
  5. {
  6. tmp4_1;
  7. CGLIB$BIND_CALLBACKS(this);
  8. }
  9. MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;
  10. if (tmp17_14 != null) {
  11. return (String)tmp17_14.intercept(this, CGLIB$getName$0$Method, new Object[] { new Integer(paramInt) }, CGLIB$getName$0$Proxy);
  12. }
  13. return super.getName(paramInt);
  14. }

CGLIB$CALLBACK_0 是cglib MethodInterceptor 对象

由于jd-gui无法完全反编译 看不到CGLIB$getName$0$Proxy  MethodProxy 对象是如何生成的

我们用javap 看下 getName 生成多少条指令大概知道为什么会慢

javap -v TestProxy$UserServiceImpl$$EnhancerByCGLIB$$aa69a57.class > d.txt

  1. public final java.lang.String getName(int);
  2. descriptor: (I)Ljava/lang/String;
  3. flags: ACC_PUBLIC, ACC_FINAL
  4. Code:
  5. stack=9, locals=2, args_size=2
  6. 0: aload_0
  7. 1: getfield #40 // Field CGLIB$CALLBACK_0:Lnet/sf/cglib/proxy/MethodInterceptor;
  8. 4: dup
  9. 5: ifnonnull 17
  10. 8: pop
  11. 9: aload_0
  12. 10: invokestatic #44 // Method CGLIB$BIND_CALLBACKS:(Ljava/lang/Object;)V
  13. 13: aload_0
  14. 14: getfield #40 // Field CGLIB$CALLBACK_0:Lnet/sf/cglib/proxy/MethodInterceptor;
  15. 17: dup
  16. 18: ifnull 53
  17. 21: aload_0
  18. 22: getstatic #46 // Field CGLIB$getName$0$Method:Ljava/lang/reflect/Method;
  19. 25: iconst_1
  20. 26: anewarray #48 // class java/lang/Object
  21. 29: dup
  22. 30: iconst_0
  23. 31: iload_1
  24. 32: new #50 // class java/lang/Integer
  25. 35: dup_x1
  26. 36: swap
  27. 37: invokespecial #53 // Method java/lang/Integer."<init>":(I)V
  28. 40: aastore
  29. 41: getstatic #55 // Field CGLIB$getName$0$Proxy:Lnet/sf/cglib/proxy/MethodProxy;
  30. 44: invokeinterface #61, 5 // InterfaceMethod net/sf/cglib/proxy/MethodInterceptor.intercept:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;Lnet/sf/cglib/proxy/MethodProxy;)Ljava/lang/Object;
  31. 49: checkcast #63 // class java/lang/String
  32. 52: areturn
  33. 53: aload_0
  34. 54: iload_1
  35. 55: invokespecial #38 // Method com/eyu/onequeue/TestProxy$UserServiceImpl.getName:(I)Ljava/lang/String;
  36. 58: areturn

从数量上看比jdk生成的指令差不多有二倍多,慢是必然的,但cglib比jdk1.6快,原因是jdk1.6生成差不多有上百代指令

顺便说下spring 代理有两种模式 1.cglib 2.jdk

proxyTargetClass 属性,设置为true,则使用CGLIB代理,此属性默认为false,使用JDK动态代理

  1. <aop:scoped-proxy proxy-target-class="true" />

[编织消息框架][JAVA核心技术]cglib动态代理的更多相关文章

  1. [编织消息框架][JAVA核心技术]jdk动态代理

    需要用到的工具  jdk : javac javap class 反编译 :JD-GUI http://jd.benow.ca/ import java.lang.reflect.Invocation ...

  2. [编织消息框架][JAVA核心技术]动态代理介绍

    由于java是种强类型静态语言,在执行时无法动态生成代码,静态语言基本都有这特性 动态生成代码有几种好处,也是弱类型语言的优点 1.部份逻辑可以实现热更新 2.远程调用实现非常适合 3.能动态生成扩展 ...

  3. [编织消息框架][JAVA核心技术]动态代理应用12-总结

    动态代理这篇比较长,是框架组成的重要基础 回顾下学到的应用技术 1.异常应用 2.annotation技术 3.数值与逻辑分享 4.jdk.cglib.javassist等动态代理技术 5.懒处理.预 ...

  4. [编织消息框架][JAVA核心技术]异常应用

    QException是项目业务异常基类 按模块划分子类异常,方便定位那块出错 有个来源码属性code作用定位某个功能处理出错逻辑,数字类型节省内存空间,同时减少创建子类的子类 QSocketExcep ...

  5. [编织消息框架][JAVA核心技术]annotation基础

    应用动态代理技术要先掌握annotation技术 注解是JDK1.5之后才有的新特性,JDK1.5之后内部提供的三个注解 @Deprecated 意思是“废弃的,过时的” @Override 意思是“ ...

  6. [编织消息框架][JAVA核心技术]动态代理应用4

    基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...

  7. [编织消息框架][JAVA核心技术]动态代理应用8-IRpcReceive实现

    private static Map<Short, Map<Byte, Method>> RECEIVE_METHOD_INFO = new HashMap<>() ...

  8. [编织消息框架][JAVA核心技术]动态代理应用7-IRpcSend实现

    根据设计生成两个接口,IRpcSend send方法返回数据要求包装成QResult对象 public interface IRpcSend { public <T> QResult< ...

  9. [编织消息框架][JAVA核心技术]动态代理应用4-annotationProcessor

    基础部份: 接下来讲编译JAVA时,生成自定义class 我们用 javax.annotation.processing.AbstractProcessor 来处理 public abstract c ...

随机推荐

  1. Servlet&JSP-HTTP服务器响应信息

    完整代码请参考:https://github.com/devway9/java-exercise/tree/master/servlet-jsp 目录 1 HTTP响应的格式 2 如何设置状态代码 3 ...

  2. Libevent 反应堆的初始化

    // 默认情况下new eventbase struct event_base * event_base_new(void) { struct event_base *base = NULL; //初 ...

  3. Makefile中的变量和shell变量

    我们在写makefile时 多多少少会用到shell脚本, 对于变量的在shell中的使用有一些要注意的细节.让我们从一个简单的makefile来看看. 注意makefile中一定要有一个目标,且一定 ...

  4. NYOJ 119 士兵杀敌(三) RMQ ST

    NYOJ 119 士兵杀敌(三) RMQ ST 题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=119 思路: ST在线 预处理O(nlog ...

  5. 推荐一个非常牛逼的并发httpful的库(php)

    MultiHttp :结合了libcurl多线程.httpful方式的PHP库 This is high performance curl wrapper written in pure PHP. I ...

  6. Android开发之监听发出的短信

    执行效果图: 预备知识: 为了监听指定的ContentProvider的数据的改变,须要通过ContentResolver向指定Uri注冊CotentObserver监听器.ContentResolv ...

  7. Linux性能及调优指南(翻译)之Linux进程管理

    本文为IBM RedBook的Linux Performanceand Tuning Guidelines的1.1节的翻译原文地址:http://www.redbooks.ibm.com/redpap ...

  8. Comparable和Comparator的差别

    原文地址:http://leihuang.org/2014/11/16/Comparable-Vs-Comparator/ Comparable和Comparator都是用来实现集合中元素的比較.排序 ...

  9. POJ 1469(裸二分匹配)

    COURSES Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18993   Accepted: 7486 Descript ...

  10. STL之list容器的实现框架

    说明:本文仅供学习交流,转载请标明出处.欢迎转载! list的底层採用数据结构是环形的双向链表. 相对于vector容器.list容器插入和删除操作付出的代价要比vector容器小得多,可是list带 ...