`
Kingson_Wu
  • 浏览: 111314 次
文章分类
社区版块
存档分类
最新评论

Java代理 Notes

 
阅读更多
  • 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
  • 动态代理:在程序运行时,运用反射机制动态创建而成。
    java静态代理和动态代理:http://layznet.iteye.com/blog/1182924

实际测试中,JDK的动态类创建过程很快,这是因为在这个内置实现中defineClass()方法被定义为native实现,故性能高于其它几种实现。但在代理类的函数调用性能上,JDK的动态代理就不如CGLIB和Javassist的基于动态代理的代理。
https://segmentfault.com/a/1190000004360241

静态代理不使用反射
jdk动态代理生成的字节码也是使用反射调用被代理的方法
javaassist?
cglib?
asm?

不得不说的AOP——基于Javassist的动态代理实现http://exolution.iteye.com/blog/1460833

javaasist动态代理实现原理??


深入剖析动态代理–性能比较:http://blog.csdn.net/liutengteng130/article/details/46565309
Java查看动态代理生成的代码:http://www.cnblogs.com/ctgulong/p/5011614.html


JDK 动态代理

  • JDK动态代理实现原理http://rejoy.iteye.com/blog/1627405
    JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。
  • Java的动态代理

    1. JAVA自带的动态代理是基于java.lang.reflect.Proxy、java.lang.reflect.InvocationHandler两个类来完成的,使用JAVA反射机制。
      通常使用下面方法创建代理对象:
    2. Object proxy = Proxy.newProxyInstance(定义代理对象的类加载器,要代理的目标对象的归属接口数组,回调接口InvocationHandler);
    3. JDK的动态代理会动态的创建一个$Proxy0的类,这个类继承了Proxy并且实现了要代理的目标对象的接口,但是在JDK中是找不到这个类的,因为它是动态生成的。
    4. 目标对象的方法调用被Proxy拦截,在InvocationHandler中的回调方法中通过反射调用。这种动态代理的方法实现了对类的方法的运行时修改。
      来自:http://blog.sina.com.cn/s/blog_548c8a8301013j6u.html
  • JDK也是通过字节码生成来实现动态代理的,但生成的字节码也是用反射的方式调用被代理对象的方法。


Cglib

  • JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

  • CGLib所创建的动态代理对象的性能比JDK的高大概10倍,但CGLib在创建代理对象的时间比JDK大概多8倍,所以对于singleton的代理对象或者具有实例池的代理,因为无需重复的创建代理对象,所以比较适合CGLib动态代理技术,反之选择JDK代理。值得一提的是由于CGLib采用动态创建子类的方式生成代理对象,所以不能对目标类中final的方法进行代理。
    来自http://www.xuebuyuan.com/324257.html

  • CGLib动态代理原理及实现:http://blog.csdn.net/yakoo5/article/details/9099133/
    CGLIB 和 JDK生成动态代理类的区别:http://luyuanliang.iteye.com/blog/1137292

  • cglib封装了asm,可以在运行期动态生成新的class。

  • CGLIB原理
    1. CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。
    2. CGLIB底层:使用字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
    3. CGLIB缺点:对于final方法,无法进行代理。
      来自http://shensy.iteye.com/blog/1867588

Spring AOP

    1. 基于JDK动态代理 ,可以将@Transactional放置在接口和具体类上。
    2. 基于CGLIB类代理,只能将@Transactional放置在具体类上。
      因此 在实际开发时全部将@Transactional放到具体类上,而不是接口上。
      建议大家使用基于Schema风格的事务(不用考虑这么多问题,也不用考虑是类还是方法)。而@Transactional建议放置到具体类上,不要放置到接口。
      来自http://jinnianshilongnian.iteye.com/blog/1508018
  • <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
    该配置方式是基于CGLIB类代理

    1. Spring使用JdkDynamicAopProxy实现代理
    2. Spring将使用CGLIB动态代理,而内部通过Cglib2AopProxy实现代理,而内部通过DynamicAdvisedInterceptor进行拦截
  • Spring中JDK动态代理和CGLIB动态代理的性能比较:
    http://www.thinksaas.cn/group/topic/130731/


动态代理方案性能对比:

  • 测试结论:

    1. ASM和JAVAASSIST字节码生成方式不相上下,都很快,是CGLIB的5倍。
    2. CGLIB次之,是JDK自带的两倍。
    3. JDK自带的再次之,因JDK1.6对动态代理做了优化,如果用低版本JDK更慢,要注意的是JDK也是通过字节码生成来实现动态代理的,而不是反射。 (个人理解应该说不是简单的使用反射,而是使用字节码生成类,这类会使用反射调用)
    4. JAVAASSIST提供者动态代理接口最慢,比JDK自带的还慢。
      (这也是为什么网上有人说JAVAASSIST比JDK还慢的原因,用JAVAASSIST最好别用它提供的动态代理接口,而可以考虑用它的字节码生成方式)
  • 差异原因:
    各方案生成的字节码不一样,
    像JDK和CGLIB都考虑了很多因素,以及继承或包装了自己的一些类,
    所以生成的字节码非常大,而我们很多时候用不上这些,
    而手工生成的字节码非常小,所以速度快

  • 最终选型:
    最终决定使用JAVAASSIST的字节码生成代理方式,
    虽然ASM稍快,但并没有快一个数量级,
    而JAVAASSIST的字节码生成方式比ASM方便,
    JAVAASSIST只需用字符串拼接出Java源码,便可生成相应字节码,
    而ASM需要手工写字节码。

  • 评论

    1. 请问 用动态代理生成的bytecode是如何从jvm里导出来的?谢谢
      可以用:
      javap -c 类名
    2. 这样的测试对cglib不公平,因为javassit采用的是直接调用,而cglib走了methodProxy.invoke(),说白了还是反射调用。
      可以实施cglib的直接调用,比如使用的Dispatcher或则LazyLoader。最后的生成的字节就是一个直接调用,性能上就可以和javassist持平。
class DirectService implements Dispatcher {  

    public Object loadObject() throws Exception {  
        return service;  
    }  

}  

来自:<http://javatar.iteye.com/blog/814426/>

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
分享到:
评论

相关推荐

    Domino notes java版导出excel

    Domino notes java版导出excel,需要组件poi支持,解决Domino日常数据批量导出需求!

    notes:JavaJava后端工程师的学习笔记https

    loveincode's notes 学习工作中的一些记录,收藏。 操作系统 , 编译原理 , 计算机网络 , 互联网协议... 常用数据结构与算法 Java 实现 数据结构 与 排序算法 常用设计模式 单例模式 , 工厂模式 , 装饰者模式 , 代理...

    LotusDomino学习笔记(400页涵盖代理和公式使用)

    108. Shortcut when printing from a Java Agent 278 109. Lotus Script: Write # statement 279 110. Lotus Script: Input # statement 280 111. 使用代理生成 XML 284 112. 使用视图生成 XML 286 113. 执行算术...

    代理中Domino对域的解析和GetItemValue使用方法

    Notes里提供了一个可以放在浏览器里的富文本Java(不是JavaScript)小程序,从而可以得到富文本的一些功能,但是你并不能用JavaScript来对它编程,而且它也不是一个真正的HTML对象类型。  更让Notes开发人员惊讶的是...

    notes:一个记笔记的 webapp 原型

    使用 Java 代理的网页剪辑 我试图关注的其他要求 连通性 嵌入 外部超链接 内部超链接 进出口 分享 分类 海拉基 标签/关键字 文档的属性 文本布局和格式 时间感 日历 计时器/提醒 % 完全的 完成日期 使用方便 视觉...

    安卓java读取网页源码-AndroidLearningNotes:第一次提交

    AndroidLearningNotes Java Java基础面试知识 int与integer的区别 探探对java多态的理解 String、StringBuffer、StringBuilder区别 什么是内部类?内部类的作用 抽象类的意义 抽象类与接口的应用场景 抽象类是否可以...

    Lotus.Domino.Web编程

    8.3.1 简单Java代理:Simple Agent.Java 191 8.3.2 多线程代理程序:NotesGuiAgent. java 196 8.3.3 Java Web代理程序 199 8.4 在R5中编写Java代理 226 参考信息 230 本章小结 231 第9章 使用Java小应用程序 232 ...

    lotus domino附件开发--附件批量放到一个文档

    Lotus Domino 附件开发 -- 附件批量放到一个文档是 Lotus Domino 附件开发中的一种常见操作,通过使用 LotusScript 语言和 Notes 对象可以实现附件批量放到一个文档。本文对代码进行了详细的解释,希望能够帮助读者...

    Learning-Notes:学习笔记

    Java maven netty Redis Spring Spring4新特性 Spring使用注意事项 Spring验证Validation SpringBoot 开发知识 相关技术名词 开发技术框架工具整理 架构知识 开发过程注意事项整理 常用开发技巧 数据库 数据库基础...

    移动代理源代码

    Notes To use the prototype there must be at least one video presentation, and register it to the middleware. Therefore we included a presentation in this distribution that is starWarsH263Medium.mov. ...

    java-servlet-api.doc

    Java Servlet API说明文档 绪言 这是一份关于2.1版JavaServletAPI的说明文档,作为对这本文档的补充,你可以到http://java.sun.com/products/servlet/index.html下面下载Javadoc格式的文档。 谁需要读这份文档 这份...

    worldwindjava源码-SANS_FOR572_GNFA_Exam_Notes:SANS_FOR572_GNFA_Exam_Notes

    世界风java源码为什么要进行网络取证? 识别 TTP(战术、技术、程序) 奥卡姆剃刀并不总是适用:混淆调查员(adv. 攻击者故意的虚假证据或不成熟的嫌疑人的行为):战略目标。 攻击者停留时间:攻击者首次获得对公司...

    matlab代码做游戏-Reinforcement-Learning-Notes-2:强化学习笔记2

    -基于Java的强化学习框架 -平台实施Q学习和其他RL算法 -贝叶斯强化学习库和工具包 -使用Google Tensorflow进行深度Q学习演示 -Torch中的深层Q网络和异步代理 -使用Theano + Lasagne进行深度强化学习和自定义递归网络...

    leetcode答案-Data-Structure-and-Algorithms:数据结构与算法

    Nigix反向代理(精力允许可以更进一步): 浏览器基础 浏览器缓存 浏览器灵魂之问: 浏览器渲染原理 现代浏览器是如何工作的(P1): 现代浏览器是如何工作的(P2): 现代浏览器是如何工作的(P3): 现代浏览器

    LotusDomino学习笔记.doc

    108. Shortcut when printing from a Java Agent 278 109. Lotus Script: Write # statement 279 110. Lotus Script: Input # statement 280 111. 使用代理生成 XML 284 112. 使用视图生成 XML 286 113. 执行算术...

    Lotus Domino WEB 开发技术积累-DOC(313页)

    108. Shortcut when printing from a Java Agent 278 109. Lotus Script: Write # statement 279 110. Lotus Script: Input # statement 280 111. 使用代理生成 XML 284 112. 使用视图生成 XML 286 113. 执行算术...

    Lotus Domino WEB详细 学习笔记

    108. Shortcut when printing from a Java Agent 278 109. Lotus Script: Write # statement 279 110. Lotus Script: Input # statement 280 111. 使用代理生成 XML 284 112. 使用视图生成 XML 286 ...

    GameOfLife:16.35 项目

    ##Project Notes ###Simulator 类时间步骤,有独占锁更新屏幕设置每个代理线程运行的数量 ###Grid 类原点在左上角 0 索引持有瓷砖 有实际的网格 是否重新绘制操作,因为它具有所有信息 ###Tile class x, y ID = y*...

    data-lifecycle-service-broker:用于管理数据生命周期的 Cloud Foundry Service Broker

    #Test Env Setup 这将构建一个用于测试的 postgres 环境。 创建专有网络创建一个新的 ubuntu 机器(t1.micro 很好而且免费) apt-get 更新按照apt-get 安装 postgres... #Notes 我们先试一试,然后制作一个 AMI,然后

    BlackBerry开发平台配置及入门介绍(傻瓜教程)

     1、采用开放的标准(Java)、满足IT部门的严格技术要求;  2、使用方便,采用端到端的安全加密措施;  3、实时在线、永远连接  典型应用  一 典型应用  1、 应用描述  A公司是一家外资独资公司,在北京、海南...

Global site tag (gtag.js) - Google Analytics