java - 如何在 ByteBuddy 转换期间增加方法?

标签 java bytecode byte-buddy bytecode-manipulation

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

  • 扩充原有方法
  • 完全创建新方法
  • 扩充通过 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作为论据。
    问题
    简而言之:如果遵循后者,我看不到前者的转换。
    实际执行顺序如下:
  • 我的类型被处理并通过 MethodDelegation.… 添加了一个方法.
  • 在随后的步骤中,我找到了新引入的方法,并尝试通过 Advice.to(…) 来增加实现生成。使用 @OnMethodExit建议。
  • 生成的代码具有第 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!和代表团!。

    关于java - 如何在 ByteBuddy 转换期间增加方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66489614/

    相关文章:

    java - 启动 Tomcat 时出现 ClassNotFoundException DispatcherServlet(Maven 依赖项未复制到 wtpwebapps)

    java - 用动态生成的类替换反射调用

    byte-buddy - 拦截签名类的策略

    java - 如何使用 Bytebuddy 拦截字段访问(无需 getter/setter)

    Java:在运行时从同一 JVM 中获取类的字节码

    java - "add one more entry"模式类的好名字

    java - Java 枚举/迭代器的使用

    java - 在 Java 9 中使用必需参数和可选参数构建抽象父类(super class)的子类对象的最佳方法是什么?

    bytecode - 每次到达该行时是否重新解释解释语言的代码?

    Java 字节码反编译——存在未使用的方法?