ASM函数监听实现(二)之打印注入函数的参数值

上一篇博客中实现了asm简单的对类中方法添加监听。

[url]http://xkorey.iteye.com/admin/blogs/1551897[/url]

监听只是一个简单的切入并未对所切入方法的值做任何处理。

简单的打印出了



it's begin
helloWorld....
it's end


这次也做一点小改动,将改为


start value:hello
end value:hello world


将实现:监听函数的传入值。

首先将测试类 helloWorld 改造为:


public class helloWorld {

public void sayHello(String parm){
parm+=" world";
}
}


其次改造 asmAopMethodAdapter 对方法做修改的类,


public class asmAopMethodAdapter extends MethodAdapter implements Opcodes{

private final static int EXCEPTION_STACK = 2 + 1;//max_stack至少需要能够容纳2个常量地址(监控方法使用)和1个exception地址

private Label try_catch_start,try_catch_end;

private String startInfo,endInfo;

public asmAopMethodAdapter(MethodVisitor mv,String start,String end) {
super(mv);
try_catch_start = new Label();
try_catch_end = new Label();
startInfo = start;
endInfo = end;
}

public void visitCode() {
mv.visitCode();
mv.visitLabel(try_catch_start);

mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
// mv.visitLdcInsn(startInfo);
//asmAopInvoker 这里写类的路径例如:com.asm.asmAopInvoker 应写成 com/asm/asmAopInvoker
mv.visitMethodInsn(INVOKESTATIC, "asmAopInvoker",
"methodStart", "(Ljava/lang/String;)V");
}

public void visitInsn(int opcode){
if(opcode >= IRETURN && opcode <= RETURN){

mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
//mv.visitLdcInsn(endInfo);
//asmAopInvoker 这里写类的路径例如:com.asm.asmAopInvoker 应写成 com/asm/asmAopInvoker
mv.visitMethodInsn(INVOKESTATIC, "asmAopInvoker",
"methodEnd", "(Ljava/lang/String;)V");
}
mv.visitInsn(opcode);
}
public void visitEnd() {
mv.visitLabel(try_catch_end);
mv.visitTryCatchBlock(try_catch_start, try_catch_end, try_catch_end, null);
//mv.visitLdcInsn(endInfo);
//asmAopInvoker 这里写类的路径例如:com.asm.asmAopInvoker 应写成 com/asm/asmAopInvoker
//mv.visitMethodInsn(INVOKESTATIC, "asmAopInvoker",
"methodEnd", "(Ljava/lang/String;)V");
mv.visitInsn(Opcodes.ATHROW);
mv.visitEnd();
}

public void visitMaxs(int maxStack,int maxLocals){
//保证max stack足够大
mv.visitMaxs(Math.max(EXCEPTION_STACK,maxStack), maxLocals);
}
}


其中改变的部分是


// 个人理解:是将一个Object写入到class中
mv.visitLdcInsn(endInfo);

改为

// 个人理解:访问方法内的第一个参数
mv.visitVarInsn(ALOAD, 0);
// 个人理解:获取这个参数的值
mv.visitVarInsn(ALOAD, 1);


这次运行环境依旧是jdk1.6,asm 3.3.1

其中的类已打包。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值