public AsmMethodVisit(MethodVisitor mv) {
super(Opcodes.ASM4, mv);
}
@Override
public void visitCode() {
//此方法在访问方法的头部时被访问到,仅被访问一次
visitMethodInsn(Opcodes.INVOKESTATIC, Monitor.class.getName(), "start", "()V");
super.visitCode();
}
@Override
public void visitInsn(int opcode) {
//此方法可以获取方法中每一条指令的操作类型,被访问多次
//如应在方法结尾处添加新指令,则应判断:
if(opcode == Opcodes.RETURN)
{
visitMethodInsn(Opcodes.INVOKESTATIC, Monitor.class.getName(), "end", "()V");
}
super.visitInsn(opcode);
}
}
}
输出:
[java]
public static void AsmAopExample$Foo.execute()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
test changed method name
execute method use time :10
可以看到在execute方法中sleep 10ms,这里打印出来也是10ms,这里是在execute方法执行前先调用monitor.start()方法,方法返回是调用monitor的end方法,从而达到统计的功能,不过这里只是一个示例,如果要统计每个方法的执行时间,统计并发进行方法统计时这里当然要进行扩展,不过思路差不多就是这样。
我们查下最终生成的Foo类的class文件通过反射后的源代码:
[java]
import java.io.PrintStream;
public class AsmAopExample$Foo
{
public static void execute()
{
AsmAopExample.Monitor.start(); System.out.println("test changed method name");
try {
Thread.sleep(10L);
}
catch (InterruptedException e) {
e.printStackTrace();
}
AsmAopExample.Monitor.end();
}
}
作者:zhongweijian