使用ByteBuddy的没有空构造函数的类的代理

时间:2018-01-25 15:23:01

标签: java byte-buddy dynamic-proxy

有没有办法使用ByteBuddy为没有空构造函数的类创建代理?

我们的想法是为给定的具体类型创建代理,然后将所有方法重定向到处理程序。

此测试展示了为没有空构造函数的clas创建代理的情况,并抛出了java.lang.NoSuchMethodException

@Test
public void testProxyCreation_NoDefaultConstructor() throws InstantiationException, IllegalAccessException {

    // setup

    // exercise
    Class<?> dynamicType = new ByteBuddy() //
            .subclass(FooEntity.class) //
            .method(ElementMatchers.named("toString")) //
            .intercept(FixedValue.value("Hello World!")) //
            .make().load(getClass().getClassLoader()).getLoaded();

    // verify
    FooEntity newInstance = (FooEntity) dynamicType.newInstance();
    Assert.assertThat(newInstance.toString(), Matchers.is("Hello World!"));
}

实体:

public class FooEntity {

    private String value;

    public FooEntity(String value) {
        this.value = value;
    }

    public String getValue() {
        return this.value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

1 个答案:

答案 0 :(得分:1)

你调用subclass(FooEntity.class)暗示Byte Buddy隐含地模仿超类定义的所有构造函数。您可以添加自定义ConstructorStrategy作为第二个参数来更改此行为。

但是,JVM要求任何构造函数最终调用超级构造函数,而代理类只提供一个构造函数。给定您的代码,您可以通过简单地提供默认参数来创建代理:

FooEntity newInstance = (FooEntity) dynamicType
      .getConstuctor(String.class)
      .newInstance(null);

然后将该字段设置为null。或者,您可以使用像Objenesis这样的库来实例化类,该库使用JVM内部来创建没有任何构造函数调用的实例。