Java 如何使用cglib实现委托?

Java 如何使用cglib实现委托?,java,java-bytecode-asm,cglib,Java,Java Bytecode Asm,Cglib,这里我需要创建BImpl的实例,但是BImpl需要通过接口a访问功能。为此,类实现了这个接口A。如何在运行时连接这些BImpl接口方法的委托?其思想是BImpl可以使用A的方法 在我的例子中,A是已知的,并且AImpl实例是在运行时创建的 public static void main(String[] args) { B b = (B) Enhancer.create(BImpl.class, new MyInterceptor()); System.out.println(b.cel

这里我需要创建
BImpl
的实例,但是
BImpl
需要通过接口
a
访问功能。为此,类实现了这个接口
A
。如何在运行时连接这些
BImpl
接口方法的委托?其思想是
BImpl
可以使用
A
的方法

在我的例子中,
A
是已知的,并且
AImpl
实例是在运行时创建的

public static void main(String[] args) {
  B b = (B) Enhancer.create(BImpl.class, new MyInterceptor());
  System.out.println(b.cellValue());
}

interface A {
  String value();
}

class AImpl implements A {

  @Override
  public String value() {
    return "MyA";
  }
}

interface B {
  String cellValue();
}

abstract class BImpl implements B, A {
  @Override
  public String cellValue() {
    return value() + "MyBCell";
  }
}

class MyInterceptor implements MethodInterceptor {

  @Override
  public Object intercept(Object obj, Method method, Object[] args,
                          MethodProxy proxy) throws Throwable {
    System.out.println(method.getName());
    if ("value".equals(method.getName()))
      return method.invoke(obj, args);
    else
      return proxy.invokeSuper(obj, args);
    }
  }

你所描述的听起来像是混合模式。您不能简单地显式地实现委托吗?比如:

class BImpl implements B, A {

  private A a;

  public BImpl(A a) {
    this.a = a;
  }

  @Override
  public String cellValue() {
    return value() + "MyBCell";
  }

  @Override
  public String value() {
    return a.value();
  }
}
这应该是可能的,因为您在编译期间说您知道
A

否则,如果您确实需要在运行时执行此操作,那么您的方法可能是cglib的正确方法。但是,在调用时,您需要为
obj
传递一个不同的实例:

return method.invoke(obj, args);
否则,您将再次调用被拦截的方法,并通过在循环中点击
MyMethodInterceptor
,发现自己处于一个无止境的循环中。你也可以

如果您没有绑定到cglib,您还可以查看我的库,这使这一切更具表现力:

new ByteBuddy()
  .subclass(BImpl.class)
  .method(isAnnotatedBy(A.class))
  .intercept(Forwarding.to("a", A.class))
  .make();
生成的类现在有一个字段
a
,您可以将该字段设置为任何
a
的实例,现在将
a
接口方法的方法调用委托给该实例。例如,可以使用Java反射设置此字段。否则,您可以通过以下方式使用
静态
字段:

Forwarding.to(new A() {
  // A methods
}); 

你所描述的听起来像是混合模式。您不能简单地显式地实现委托吗?比如:

class BImpl implements B, A {

  private A a;

  public BImpl(A a) {
    this.a = a;
  }

  @Override
  public String cellValue() {
    return value() + "MyBCell";
  }

  @Override
  public String value() {
    return a.value();
  }
}
这应该是可能的,因为您在编译期间说您知道
A

否则,如果您确实需要在运行时执行此操作,那么您的方法可能是cglib的正确方法。但是,在调用时,您需要为
obj
传递一个不同的实例:

return method.invoke(obj, args);
否则,您将再次调用被拦截的方法,并通过在循环中点击
MyMethodInterceptor
,发现自己处于一个无止境的循环中。你也可以

如果您没有绑定到cglib,您还可以查看我的库,这使这一切更具表现力:

new ByteBuddy()
  .subclass(BImpl.class)
  .method(isAnnotatedBy(A.class))
  .intercept(Forwarding.to("a", A.class))
  .make();
生成的类现在有一个字段
a
,您可以将该字段设置为任何
a
的实例,现在将
a
接口方法的方法调用委托给该实例。例如,可以使用Java反射设置此字段。否则,您可以通过以下方式使用
静态
字段:

Forwarding.to(new A() {
  // A methods
}); 

你所描述的听起来像是混合模式。您不能简单地显式地实现委托吗?比如:

class BImpl implements B, A {

  private A a;

  public BImpl(A a) {
    this.a = a;
  }

  @Override
  public String cellValue() {
    return value() + "MyBCell";
  }

  @Override
  public String value() {
    return a.value();
  }
}
这应该是可能的,因为您在编译期间说您知道
A

否则,如果您确实需要在运行时执行此操作,那么您的方法可能是cglib的正确方法。但是,在调用时,您需要为
obj
传递一个不同的实例:

return method.invoke(obj, args);
否则,您将再次调用被拦截的方法,并通过在循环中点击
MyMethodInterceptor
,发现自己处于一个无止境的循环中。你也可以

如果您没有绑定到cglib,您还可以查看我的库,这使这一切更具表现力:

new ByteBuddy()
  .subclass(BImpl.class)
  .method(isAnnotatedBy(A.class))
  .intercept(Forwarding.to("a", A.class))
  .make();
生成的类现在有一个字段
a
,您可以将该字段设置为任何
a
的实例,现在将
a
接口方法的方法调用委托给该实例。例如,可以使用Java反射设置此字段。否则,您可以通过以下方式使用
静态
字段:

Forwarding.to(new A() {
  // A methods
}); 

你所描述的听起来像是混合模式。您不能简单地显式地实现委托吗?比如:

class BImpl implements B, A {

  private A a;

  public BImpl(A a) {
    this.a = a;
  }

  @Override
  public String cellValue() {
    return value() + "MyBCell";
  }

  @Override
  public String value() {
    return a.value();
  }
}
这应该是可能的,因为您在编译期间说您知道
A

否则,如果您确实需要在运行时执行此操作,那么您的方法可能是cglib的正确方法。但是,在调用时,您需要为
obj
传递一个不同的实例:

return method.invoke(obj, args);
否则,您将再次调用被拦截的方法,并通过在循环中点击
MyMethodInterceptor
,发现自己处于一个无止境的循环中。你也可以

如果您没有绑定到cglib,您还可以查看我的库,这使这一切更具表现力:

new ByteBuddy()
  .subclass(BImpl.class)
  .method(isAnnotatedBy(A.class))
  .intercept(Forwarding.to("a", A.class))
  .make();
生成的类现在有一个字段
a
,您可以将该字段设置为任何
a
的实例,现在将
a
接口方法的方法调用委托给该实例。例如,可以使用Java反射设置此字段。否则,您可以通过以下方式使用
静态
字段:

Forwarding.to(new A() {
  // A methods
});