使用 ByteBuddy 代理没有空构造函数的 class
Proxy for a class with no empty constructor using ByteBuddy
有没有办法使用 ByteBuddy 为没有空构造函数的 class 创建代理?
想法是为给定的具体类型创建代理,然后将所有方法重定向到处理程序。
此测试展示了为没有空构造函数的类创建代理的场景,它抛出 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;
}
}
您调用 subclass(FooEntity.class)
意味着 Byte Buddy 隐含地模仿了超级 class 定义的所有构造函数。您可以添加自定义 ConstructorStrategy
作为第二个参数来更改此行为。
但是,JVM 要求任何构造函数最终都调用超级构造函数,而您的代理 class 仅提供一个具有单个构造函数的构造函数。根据您的代码,您可以通过简单地提供默认参数来创建代理:
FooEntity newInstance = (FooEntity) dynamicType
.getConstuctor(String.class)
.newInstance(null);
该字段随后设置为 null
。或者,您可以使用像 Objenesis 这样的库来实例化 classes,它使用 JVM 内部机制来创建实例而无需任何构造函数调用。
有没有办法使用 ByteBuddy 为没有空构造函数的 class 创建代理?
想法是为给定的具体类型创建代理,然后将所有方法重定向到处理程序。
此测试展示了为没有空构造函数的类创建代理的场景,它抛出 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;
}
}
您调用 subclass(FooEntity.class)
意味着 Byte Buddy 隐含地模仿了超级 class 定义的所有构造函数。您可以添加自定义 ConstructorStrategy
作为第二个参数来更改此行为。
但是,JVM 要求任何构造函数最终都调用超级构造函数,而您的代理 class 仅提供一个具有单个构造函数的构造函数。根据您的代码,您可以通过简单地提供默认参数来创建代理:
FooEntity newInstance = (FooEntity) dynamicType
.getConstuctor(String.class)
.newInstance(null);
该字段随后设置为 null
。或者,您可以使用像 Objenesis 这样的库来实例化 classes,它使用 JVM 内部机制来创建实例而无需任何构造函数调用。