ASM 9.2插桩时自定义ClassVisitor除构造函数外其余方法未被调用
问题根因
你已经实例化了自定义的EnterExitClassAdapter对象ca,但调用ClassReader.accept()方法时传入的是ClassWriter实例cw,而非自定义适配器实例ca,ASM的类解析事件不会流转到你编写的自定义逻辑中,因此visit、visitMethod等方法都不会被触发。
修复方案
将你第一块代码中的cr.accept调用参数替换为适配器实例即可:
ClassReader cr = new ClassReader(classBytes); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); EnterExitClassAdapter ca = new EnterExitClassAdapter(cw, config, aspects); // 这里把入参cw改为ca cr.accept(ca, ClassReader.EXPAND_FRAMES); return cw.toByteArray();
额外注意事项
- 你的
visitMethod方法中需要调用super.visitMethod获取父类返回的MethodVisitor,并最终将该实例(或者你自定义包装后的MethodVisitor实例)返回,否则方法字节码不会传递到ClassWriter,最终生成的类会缺失对应方法,示例如下:
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodVisitor originMv = super.visitMethod(access, name, desc, signature, exceptions); // 你自己的插桩逻辑,可以自定义MethodVisitor包装originMv后返回 return originMv; }
- 若修复后出现类格式错误,可先去掉
ClassWriter的COMPUTE_FRAMES参数,手动计算操作数栈和局部变量表大小,更方便新手定位插桩逻辑问题。
内容的提问来源于stack exchange,提问作者Zader
相关产品推荐
相关产品推荐

