如何在ByteBuddy转型期间增强方法



上下文

我正在使用ByteBuddy实现字节码转换,操作过程是一个多步骤的过程。正因为如此,操纵必须能够:

  1. 扩充原有的方法
  2. 完全创建新方法
  3. 增加了通过2引入的方法

对于1。我使用了通过应用的@OnMethodExit建议

Builder<?> builder = builder.visit(Advice.to(Helper.class)
.on(ElementMatchers.hasMethodNamed(name));

Helper是该方法的扩充码(有效地设置字段的值)。在创建新方法时,我按照如下方式构建它们:

Builder<?> builder = builder.defineMethod(…)
.intercept(MethodDelegation.to(OtherHelper.class));
.…;

OtherHelper通过以@This Object object为参数的静态方法来消耗运行时实例。

问题

简言之:如果前一个变换跟随后一个变换,我看不到它的应用。实际执行顺序如下:

  1. 通过MethodDelegation.…处理我的类型并添加一个方法
  2. 在接下来的步骤中,我找到了新引入的方法,并尝试使用@OnMethodExit建议通过Advice.to(…)来增加实现生成
  3. 生成的代码具有步骤1的行为,但缺少步骤2的行为

我假设我无效地组合了实现的两个部分。有什么想法吗?直觉:按名称匹配扩充的ElementMatcher还没有看到使用….defineMethod(…)引入的方法吗?name来自于我从builder.toTypeDescription()开始的一些方法检查,这实际上让我假设要创建的方法对构建器来说已经可见,否则它就不会在该步骤中找到。

你能分享你的例子的重建吗?在一个简单的例子中,我观察到了预期的行为:

public class Bar {
public static void main(String[] args) throws Exception {
Class<?> type = new ByteBuddy().subclass(Object.class)
.visit(Advice.to(Bar.class).on(named("m")))
.defineMethod("m", void.class, Visibility.PUBLIC)
.intercept(MethodDelegation.to(Bar.class))
.make()
.load(Bar.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
type.getMethod("m").invoke(type.getConstructor().newInstance());
}
@BindingPriority(2)
public static void delegation() {
System.out.println("Delegation!");
}
@Advice.OnMethodEnter
public static void enter() {
System.out.println("Advice!");
}
}

此示例打印两个建议代表团

相关内容

  • 没有找到相关文章

最新更新