Java 如何在ByteBuddy转换期间扩充方法? 上下文

Java 如何在ByteBuddy转换期间扩充方法? 上下文,java,bytecode,byte-buddy,bytecode-manipulation,Java,Bytecode,Byte Buddy,Bytecode Manipulation,我正在用ByteBuddy实现字节码转换,操作过程是一个多步骤的过程。 因此,操纵必须能够: 扩充原有的方法 完全创建新方法 扩充通过2引入的方法 1。我使用了通过以下方式应用的@OnMethodExit建议: Builder<?> builder = builder.visit(Advice.to(Helper.class) .on(ElementMatchers.hasMethodNamed(name)); OtherHelper通过以@此对象为参数的静态方法使用运行时实例

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

  • 扩充原有的方法
  • 完全创建新方法
  • 扩充通过2引入的方法
  • 1。我使用了通过以下方式应用的
    @OnMethodExit
    建议:

    Builder<?> builder = builder.visit(Advice.to(Helper.class)
      .on(ElementMatchers.hasMethodNamed(name));
    
    OtherHelper
    通过以
    @此对象
    为参数的静态方法使用运行时实例

    问题 简言之:如果前一种转换遵循后一种转换,我看不到它被应用。 实际执行顺序如下:

    Builder<?> builder = builder.defineMethod(…)
      .intercept(MethodDelegation.to(OtherHelper.class));
      .…;
    
  • 通过
    MethodDelegation….
    处理我的类型并添加方法
  • 在随后的步骤中,我找到了新引入的方法,并尝试通过
    通知来增强实现生成。使用
    @OnMethodExit
    通知(…)
  • 生成的代码具有步骤1的行为,但缺少步骤2的行为

  • 我假设我无效地合并了实现的两个部分。有什么想法吗?预感:
    ElementMatcher
    按名称匹配扩展是否还没有看到使用
    …defineMethod(…)
    引入的方法?
    名称
    来自于某种方法检查,我从
    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!");
      }
    }
    
    公共类栏{
    公共静态void main(字符串[]args)引发异常{
    类类型=new ByteBuddy().subclass(Object.Class)
    .访问(向(律师类)提供建议。关于(名为(“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());
    }
    @绑定优先级(2)
    公共静态无效委托(){
    System.out.println(“委托!”);
    }
    @忠告,忠告
    公共静态void enter(){
    System.out.println(“通知”);
    }
    }
    

    此示例打印两条建议!还有代表团

    很尴尬。我有一个建议,将一个布尔字段初始化为
    true
    ,并在实际希望拦截该方法时重新使用它,以将该标志翻转为
    false
    。当然,在我的测试中,该标志仍然是
    true
    。这就是为什么在这里!很高兴你明白了!