使用Byte Buddy转发方法调用

时间:2015-12-28 20:14:58

标签: java bytecode byte-buddy

我试图用Byte Buddy建立一个实现给定实例的所有接口并转发所有对该实例的调用的类,这是我目前的代码:

import static net.bytebuddy.implementation.Forwarding.to;

static Class<?> save (state) {
  return stream (state.getClass ().getMethods ())
    .filter (m -> isPublic (m.getModifiers ()))
    .reduce ((Builder<?>) new ByteBuddy ().subclass (Object.class)
      .implement (state.getClass ().getInterfaces ()),
             (b, m) -> {
               System.out.println ("Setting up method " + m.getName ());
               return b.define (new ForLoadedMethod (m))
                 .intercept (to (state));
              }, (x, y) -> {
                throw new UnsupportedOperationException ();
              }).make ().load (state.getClass ()
                .getClassLoader (), INJECTION).getLoaded ();
}

public static void main (String[] args) throws Throwable {
  System.out.println ("Saved: " + save (new Integer (1)).newInstance ().toString ());
}

这会产生如下异常:

Exception in thread "main" java.lang.IllegalArgumentException: Cannot forward public boolean net.bytebuddy.renamed.java.lang.Object$ByteBuddy$rwGGy3NN.equals(java.lang.Object) to class java.lang.Integer
at net.bytebuddy.implementation.Forwarding$Appender.apply(Forwarding.java:337)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:510)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:444)

我可以看到Forwarding下的说明,它可以使其工作the intercepted method must be defined on a super type of the given delegation target,但我不确定这意味着什么。如果这意味着我应该对生成的类进行子类化,那么如果我的目标是final类呢?我还能如何创建一个转发这些调用的自定义实现?

另外,既然我在这里,我怎样才能指定要实现的通用接口类型?它是来自加载的java.lang.reflect.Type还是来自我想要动态创建的内容?

1 个答案:

答案 0 :(得分:1)

Forwarding实现类似于反射API,其中目标需要是可分配类型。由于你没有继承Integer(这是不可能的),转发委托失败。

我认为您正在寻找MethodCall委派,您可以在其中命名要显式调用的方法。这对你有用吗?

最后,实现泛型类型是针对0.8版本计划的功能。我已经取得了很好的进展,并希望在2016年1月之前准备好候选版本。我还计划重新审视转发授权,基于签名的调用不应该太难实现。