java asm工具类_使用ASM实现简单的AOP

前言

之前一直使用greys及其内部升级二次开发版来排查问题。最近周末刚好事情不多,作为一名程序员本能地想要弄懂这么神奇的greys到底是怎么实现的?周末从github上拉了代码仔细读了读,其基本技术框架是JVM attach + Instrumentation + asm实现的。关于JVM attach和Instrumentation的功能,下次再写文章介绍,本文着重于greys中非常神奇的一个类AdviceWeaver,该类使用asm代码实现了简单的aop功能,本文的实现方式基本参考该类,具体的代码放在了scrat-profiler模块中。下文将结合asm的使用方法讲解如何实现简单的aop功能。

asm简介

什么是asm?ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为(摘自网友翻译)。asm的文档请参考asm文档,文档写的比较全。主要几个重要的类为ClassReader、ClassWriter、ClassVisitor、MethodVisitor等。

ClassVisitor、MethodVisitor与AdviceAdapter

在使用ASM操作字节码之前,我们需要稍微了解下ClassVisitor,ClassVisitor用来generating and transforming compiled classes,ClassVisitor中的每个方法都对应了class file的相关部分,ClassVisitor里方法的执行顺序应该如下:

visit visitSource? visitOuterClass? ( visitAnnotation | visitAttribute )*

( visitInnerClass | visitField | visitMethod )*

visitEnd

由于本文主要讲的是enhance class,所以着重讨论下ClassVisitor Transforming classes。Transforming classes通常需要借助于两个类ClassReader与ClassWriter,ClassWriter是ClassVisitor子类,与ClassReader或者其他ClassVisitor子类一起使用来generate a modified class from one or more existing Java classes。典型的用法如下:

byte[] b1 = ...;

ClassWriter cw = new ClassWriter(0);

ClassReader cr = new ClassReader(b1);

cr.accept(cw, 0);

byte[] b2 = cw.toByteArray();

与其他ClassVisitor一起使用的典型用法如下:

byte[] b1 = ...;

ClassWriter cw = new ClassWriter(0);

// cv forwards all events to cw

ClassVisitor cv = new ClassVisitor(ASM4, cw) { };

ClassReader cr = new ClassReader(b1);

cr.accept(cv, 0);

byte[] b2 = cw.toByteArray();

由于我想实现的是方法级别的AOP增强,所以我更加关注与ClassVisitor的visitMethod方法:

public MethodVisitor visitMethod(int access, String name, String desc,

String signature, String[] exceptions) {

if (cv != null) {

return cv.visitMethod(access, name, desc, signature, exceptions);

}

return null;

}

可以看到的是该方法返回的是MethodVisitor,当我们继承ClassVisitor并且复写visitMethod返回自定义的MethodVisitor时,我们可以实现对method的字节码进行替换增强。首先我们来研究下MethodVisitor如何使用。

MethodVisitor接口中的方法调用必须按照以下的顺序:

visitAnnotationDefault?

( visitAnnotation | visitParameterAnnotation | visitAttribute )*

( visitCode

( visitTryCatchBlock | visitLabel | visitFrame | visitXxxInsn |

visitLocalVariable | visitLineNumber )*

visitMaxs )?

visitEnd

摘取ASM user guide中比较重要的几句话:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值