委托私有方法在bytebuddy与@Super语言 - possible



我试图在bytebuddy中委托一个私有方法-但我如何调用'覆盖'版本?如果我有

    TypePool typepool = TypePool.Default.ofClassPath();
    new ByteBuddy()
        .rebase(typepool.describe("Foo").resolve(), ClassFileLocator.ForClassLoader.ofClassPath())
        .method(named("getNum"))
        .intercept(MethodDelegation.to(typepool.describe("FooInterceptor").resolve()))
        .make()
        .load(typepool.describe("Foo").resolve().getClass().getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
    Foo foo1 = new Foo();
    System.out.println("Foo says " + foo1.getMessage());

public class Foo
{
    private int num = 0;
    public String getMessage()
    {
        return "Message is Foo " + getNum();
    }
    private int getNum()
    {
        return num++;
    }
}

import net.bytebuddy.implementation.bind.annotation.Super;
public class FooInterceptor
{
    public static int getNum(@Super Foo foo)
    {
        // This won't work!
        return foo.getNum() + 100;
    }
}

就编译器而言,即使@Super Foo foo将在运行时变成其他东西,我也不允许在Foo上调用私有方法。我似乎也无法反映/调用getNum() -无论@Super Foo变成什么,它似乎没有getNum()方法(尽管它确实有getMessage()方法)。

有人能给我指个方向吗?更新:

@Rafael的回答在技术上是一个很好的解决我问的问题;不幸的是,我想我的榜样是坏的。认错。我真正希望的是一个解决方案,让我在传递getNum()之前操纵参数。但事实证明,对于我的应用程序,我可能能够通过不这样做,所以如果这改变了,也许我会发布那个确切的例子。更新2:

问题完全回答了!华友世纪!

您可能想使用@SuperCall Callable。这将允许您从方法本身调用被重写的方法。但是,它不允许您从代理类中调用任何方法。

public class FooInterceptor
{
  public static int getNum(@SuperCall Callable<Integer> c) throws Exception
  {
    // This will work!
    return c.call() + 100;
  }
}

如果需要操作参数,可以使用Morph注释。它允许您在提供显式参数的同时调用方法:

public interface Morphing<T> {
  T invoke(Object[] args);
}
public class FooInterceptor
{
  public static int getNum(@Morph Morphing<Integer> m, @AllArguments Object[] args)
  {
    // This will work!
    return m.invoke(args) + 100;
  }
}

注意,你需要显式地安装接口:

MethodDelegation.to(FooInterceptor.class)
   .appendParameterBinder(Morph.Binder.install(Morphing.class));

相关内容

  • 没有找到相关文章

最新更新