如果我正确理解了您的问题,那么我已经实现了与您想要做的相同的事情,但方式不同。
使用 ASM 事件驱动的字节码修改,我首先将 someMethod( arg, arg, arg ) 重命名为 copyOf_someMethod( arg, arg, arg )。然后我创建了一个名为 someMethod( arg, arg, arg ) 的新方法,它进行了一些处理,然后调用了 copyOf_someMethod( arg, arg, arg )。
我在我实现的 ClassVisitor 的 visitMethod(..) 方法中进行了方法重命名:
MethodVisitor methodVisitor =
super.visitMethod(
methodAccess, "copyOf_" + methodName, methodDesc,
methodSignature, methodExceptions );
return methodVisitor;
在 visitMethod(..) 中,我还将所有方法签名详细信息存储在类变量中,以便在 visitEnd() 方法中使用。
我实际上将方法详细信息存储在 MethodDetail 对象中并将其放入队列中:
private Queue<MethodDetail> methodDetails = new LinkedList<MethodDetail>();
我使用我实现的 ClassVisitor 的 visitEnd() 方法创建了 someMethod( arg, arg, arg ) 的新实现。我使用 ASMFier 生成代码以放入 visitEnd() 方法。该实现利用了我之前存储在 visitMethod(..) 中的详细信息。新实现做了一些处理,然后调用了 copyOf_someMethod()。在 visitEnd() 方法中,我弹出了队列的所有 MethodDetail,并为每个 MethodDetail 调用了我之前由 ASMFier 生成的 ASM 代码。
使用这种设计,我为一种方法创建了一个代理,该方法进行了一些处理,然后调用了原始方法。请注意,原始方法已重命名为 copyOf_someMethod(..)。另请注意,我为充当代理的原始方法提供了一个新实现。
为了支持多个参数,我使用 ASMFier 为 1 arg、2 arg、3 arg 等生成不同的代码,我最多支持 7 个参数,如果被代理的方法有超过 7 个参数,则抛出 Unsupported Exception。在 visitEnd(..) 方法中,我调用了不同的代码(由 ASMFier 生成),具体取决于原始方法有多少方法参数。
我使用 javaagent 来拦截类加载并修改字节。
由于我是 ASM 的新手,也许我没有正确理解您的问题 - 但是,如果您的问题是关于创建一个代理来进行一些处理然后调用原始方法,那么我的解决方案就可以了。它似乎并不慢。其方法被代理的类的类加载时间并不比没有修改字节码慢得多。引入代码的运行速度并不慢,ASMFier 生成的 ASM 代码看起来非常快。
干杯