应用ASM修改JAVA字节码_第1页
应用ASM修改JAVA字节码_第2页
应用ASM修改JAVA字节码_第3页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

应用ASM修改JAVA字节码摘要:ASM作为一种修改JAVA二进制字节码的方法已经被许多的项目使用,它提供了灵敏多变的API,在监控应用和辅助应用日志等方面有着不可替代的地位,本文将以网络购物车结算业务为例,简单分析一下ASM是怎样完成JAVA字节码的修改。本文关键词语:AOP;ASM引言:面向对象编程方式下,业务逻辑代码中经常会耦合一些如:权限校验、事务控制和日志记录等代码,这些代码有时会影响我们业务代码的可读性,而且有时可能会影响到业务代码的强健性和正确性,例如,一个日志代码若向外抛出异常则可能影响到整个业务方法的履行失败。从代码的复用性角度看,大量一样的日志代码存在于不同的业务方法中,这样对于日志代码的维护成本也是相当高的。之所以会存在上述问题,重要是面向对象编程方式下,重要关心的是类与类之间的纵向关系,即一个类的父类是谁或一个类被那些类继承。而对于同一条理上的类之间存在什么样子的关系基本不关注,而面向切面编程更关注的是系统横向之间的关系,在类的每个方法四周组织类与类之间的关系。对于面向切面编程实现技术有许多种,但核心都是修改JAVA字节码,大体上能够分为两类:编译器修改字节码和运行期修改字节码。本文只讨论ASM在运行期修改字节码技术〔注:ASM可以以在编译期修改字节码〕。下面以网络购物车为例来展现一下ASM技术对AOP〔AspectOrientedProgramming,面向切面编程〕的支持。1、网络购物车结算业务功能介绍:用户在网上选购完自己喜欢的商品后,能够在购物车界面查看到自己已经选购的商品,而且还能够在页面最下面点击结算按钮完成本次购物,结算后会跳转到结算成功页面,并显示实际的付款金额。第一,由于是网络购物系统,为了安全我们在网页当中隐藏了一个令牌,每次用户提交时都会去校验当下提交的恳求中的令牌能否有效,若有效才能够进行余下的操作。第二,每次用户的操作都要做相应的业务日志的记录,这就要求我们的业务代码履行完毕后能够记录相应的操作日志。总体上完成这样的功能,按面向对象编程方式,基本上是会把校验令牌和日志记录耦合在业务代码中。技术介绍:ASM是一个JAVA字节码分析、开创建立和修改的开源应用框架。在ASM中提供了众多的API用于对类的内容进行字节码操作的方法。与传统的BCEL和SERL不同,在ASM中提供了更为优雅和灵敏的操作字节码的方式。当前ASM已被广泛的开源应用架构所使用,例如:Spring、Hibernate等,ASM能够分析一个类、从字节码角度开创建立一个类和修改已经编译过的字节码文件。ASM提供了两组API:Core和Tree,Core是基于访问者形式来操作类,而Tree是基于树节点来操作类,本文我们重要使用CoreAPI,ASMCoreAPI的核心接口是ClassVisitor、ClassWriter和XXXVisitor(AnnotationVisitor、FieldVisitor、MethodVisitor等)2.1ClassVisitor:这个类会提供你要改变的类的字节数组,它的accept方法,承受一个详细的ClassVisitor,并调用实现中详细的visit,visitSource,visitOuterClass,visitAnnotation,visitAttribute,visitInnerClass,visitField,visitMethod和visitEnd方法。2.2ClassWriter:ClassVisitor的一个实现类,这个类中的toByteArray方法会将最终修改的字节码以byte数组形式返回,在这个类的构造时能够指定让系统自动为我们计算栈和当地变量的大小(COMPUTE_MAXS),可以以指定系统自动为我们计算栈帧的大小(COMPUTE_FRAMES)。2.3XXXVisitor:接口定义了和属性构造相对应的方法,这些方法能够操作属性、方法和注释等ASM的操作流程,首先是获得其二进制的字节码,即用ClassReader来读取一个类,然后需要一个能将二进制字节码写回的类,即用ClassWriter类,最后就是一个事件过滤器,即ClassAdapter。事件过滤器中的某些方法能够产生一个新的XXXVisitor对象,当我们需要修改对应的内容时只要实现自己的XXXVisitor并返回,最终会构成新的二进制代码。3、用ASM实现网络购物车结算功能:业务功能介绍时,已经给出了相应的要实现内容,这里我们重要关注的是怎样用ASM去实现令牌的校验和日志的记录,对于业务数据的操作不是我们所关注的,由于他们用原有的面向对象方式完全能够实现。首先我们需要一个核心业务类,即将用户所选的商品的价格进行求和并记录到数据库中,这个类定义如下:classBalanceService{...publicBigDecimalbalance(ListgoodsList){//计算价格和BigDecimalsum=newBigDecimal(0);for(Goodsgoods:goodsList){(ce());}lanceSum(sum);returnsum;}...}期望得到的类应该是如下类型:classBalanceService{...publicBigDecimalbalance(ListgoodsList){//校验令牌Method1();//计算价格和BigDecimalsum=newBigDecimal(0);for(Goodsgoods:goodsList){(ce());}lanceSum(sum);//记录日志Method2();returnsum;}...}Method1和Method2是要在运行期动态植入的,要植入这两个方法就需要一个方法MethodVisitor,由于MethodVisitor是一个接口所以我们要实现这个接口,幸运的是ASM为我们提供了一个简单的实现MethodAdapter,我们只要继承这个类且实现visitCode,在visitCode方法中添加方法Method1内要的操作即可实现将Method1的操作植入到balance方法中。要植入Method2方法内要操作的内容能够实现visitInsn方法,visitInsn方法它是ASM访问到无参数指令时调用的,我们balance方法履行的最后一个指令是“return〞指令,这个指令在JVM虚拟机的指令集中是一个无参指令,所以我们只要判定当下调用visitInsn传递的指令是不是〞return〞指令即可,若是则调用修改相应的字节码代码。在应用中提供一个自定义的类加载器这样就能够在类加载时嗲用相应的ModifyMethodClassAdapter方法来动态的实现对balance方法的修改。这样完成了将无关的业务代码动态植入的目的。4、总结:ASM对JAVA字节码的动态修改能够将业务代码和非业务代码进行了很好的解耦,相互之间互相独立,互不

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论