如何组合两个非Implementation.Composable类型的Implementation实例?
Byte Buddy 非Composable类型Implementation实例组合方案
核心原理
任意Implementation实例组合的前提是保证操作数栈状态符合JVM字节码规范,直接拼接两个实现时如果前一个实现执行后在栈顶遗留了未消费的返回值,会导致后一个实现的栈深度计算异常,触发字节码验证错误。
通用实现方案
使用Implementation.Compound作为组合容器,根据业务需求手动对齐两个实现之间的栈状态即可:
- 如果不需要前一个实现的返回值:在两个实现之间插入栈顶弹出操作清理状态
- 如果需要前一个实现的返回值作为后一个实现的输入:无需额外处理,直接按顺序拼接即可
针对示例场景的代码实现
需求为按顺序执行advisedMethodCall后返回第一个参数,对应实现如下:
import net.bytebuddy.implementation.Implementation; import net.bytebuddy.implementation.bytecode.Removal; Implementation advisedMethodCall = Advice.to(...).wrap(someMethodCall); Implementation firstArgument = FixedValue.argument(0); // 组合两个Implementation实例 Implementation combined = new Implementation.Compound( // 第一步:执行增强后的方法调用 advisedMethodCall, // 第二步:弹出advisedMethodCall的返回值,清理操作数栈 Removal.of(advisedMethodCall.getInstrumentedMethod().getReturnType()), // 第三步:压入第一个参数作为方法最终返回值 firstArgument );
补充说明
你观察到的MethodCall通过TerminationHandler实现组合的逻辑,本质就是框架内部自动完成了栈状态的对齐操作。对于任意非Implementation.Composable子类的实现,只要手动处理好栈状态,都可以通过Implementation.Compound完成自由组合。
内容的提问来源于stack exchange,提问作者Laird Nelson
相关产品推荐
相关产品推荐

