微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 ByteBuddy 转换期间扩充方法?

如何解决如何在 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. 在随后的步骤中,我找到了新引入的方法,并尝试使用 Advice.to(…) 建议通过 @OnMethodExit 增强实现生成
  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!");
  }
}

这个例子打印了Advice!Delegation!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。