当前位置: 首页 > 知识库问答 >
问题:

如何在ByteBuddy转换期间增强方法?

汪庆
2023-03-14

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

  1. 扩充原有方法

对于1。我使用了一个通过以下方式应用的OnMethodExit建议:

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

使用Helper方法的增强代码(有效地设置字段的值)。创建新方法时,我按如下方式构建它们:

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

另类助手通过以@This Object对象参数的静态方法使用运行时实例。

简而言之:如果前面的转换遵循后者,我看不到前面的转换应用。实际执行顺序如下:

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

我假设我无效地结合了实现的两个部分。有什么想法吗?预感:元素匹配器(ElementMatcher)是否没有看到使用引入的方法…。defineMethod(…)还没有?名称来自我从构建器开始的某种方法检查。toTypeDescription(),这实际上使我假设要创建的方法对于生成器来说已经是可见的,否则它首先不会在该步骤中找到。

共有1个答案

曾华翰
2023-03-14

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

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!");
  }
}

此示例打印建议!和委托!。

 类似资料:
  • 问题内容: 在SQL Server 2005中,为什么这样做: 展示: 1900年1月1日上午12:00 我会以为应该的吗? 问题答案: 空字符串将强制转换为,之后将强制转换为时代日期。 与不同,区分和一个空字符串。

  • 因此,我尝试使用ByteBuddy的能力来创建可以从@Advice.onMethodEnter保留到@Advice.onMethodExit的局部变量。这将允许我在方法enter上创建OpenTracing跨度,并在方法Exit上完成它。不过,我不确定我的用例是否有效,因为我使用的是一个转换器,它与@advice.local注释的测试用例不完全匹配。 我试图遵循这个测试用例中使用的语法。 但是,s

  • 在Java中获取计数后,如何将“时间戳”转换为? 我目前的代码如下: 这里我得到的输出是2012-08-07 0,但是等效查询返回3。为什么我得到0?

  • 使用ByteBuddy,我可以通过调用另一个实例方法并转换结果来实现一个实例方法吗? 例如(玩具): 鉴于上述情况,我能否实现,以便它调用并返回返回字符串的长度?也就是说,好像它是: 我天真地尝试了以下方法: 然而,看起来我的想法是错误的,;它看起来像是在生成的实例上调用的。 我还试过一个拦截器: 与: 这运行了,但产生了毫无意义的结果,在中设置断点和/或添加打印语句表明它永远不会被调用;所以很明

  • 我正在逐个迭代字符串对象列表中的元素: 在这里,每次我调用list上的get()时,列表都会从其一端一直迭代到第i个元素——因此上面循环的复杂性是O(n^2)。 是a.)对于增强型for循环,与上面相同,还是b.)对于循环,将指针保持在最后一个指针所在的位置,因此下面循环的复杂性是O(n)? 如果上面的情况(b)——我想是这样的——在列表上使用迭代器有什么好处吗。这是简单的迭代--没有回头路 蒂亚

  • 一个较长的生命周期可以强制转成一个较短的生命周期,使它在一个通常情况下不能工作的作用域内也能正常工作。这种形式出现在编译器推导强制转换的时候,也出现在声明生命周期不同的时候(原文:This comes in the form of inferred coercion by the Rust compiler, and also in the form of declaring a lifetime