我试图通过ASM跟踪方法依赖性。例如,假设我有这样的课程:
class Test{
public void methodToRun(){
Depedencies.startTracking();
//method calls here
Depedencies.stopTracking();
}
}
和methodToRun
被调用。由于我有Depedencies.startTracking()
我需要开始打印所有方法调用详细信息,我仍然看到Depedencies.stopTracking()
。
我尝试使用以下代码通过ASM执行此操作:
public class ClassPrinter extends ClassVisitor {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
MethodAdapter adapter = new MethodAdapter(mv);
return mv == null ? null : adapter;
}
}
然后适配器看起来像这样:
class MethodAdapter extends MethodVisitor implements Opcodes {
public MethodAdapter(final MethodVisitor mv) {
super(ASM5, mv);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if(name.contains("startTracking")){
System.out.println("Started tracking")
TrackerState.startTrack();
}else if(name.contains("stopTracking")) {
System.out.println("End of tracking")
TrackerState.stopTrack();
}
if(TrackerState.status())
{
//print the details.
}
mv.visitMethodInsn(opcode,owner,name,desc,itf);
}
}
class TrackerState {
private boolean static track = false;
public static void startTrack(){
track = true;
}
public static void stopTrack() {
track = false;
}
public static boolean status() {
return track
}
}
上述ASM代码仅适用于一级方法调用跟踪。意思是,它没有跟踪方法是否调用另一个方法(我应该跟踪它),下面的代码解释了问题:
class Test {
public void methodRunning()
{
Depedencies.startTracking();
method1() //tracked , but method1's method calls doesnt get tracked
method2() //tracked , , but method2's method calls doesnt get tracked and so on
Depedencies.stopTracking();
otherMethod() // not tracked as expected.
}
}
如何通过ASM处理此案例?
答案 0 :(得分:1)
如果您想访问method1()
和method2()
的内容,则需要使用您用来检查Test
的相同技术单独访问它们。
如果有任何递归或继承,那可能会变得棘手。
在第一种情况下,问题在于找出停止条件(以避免无限递归),在第二种情况下,找出要访问的方法的具体实现。