Прокси для класса без пустого конструктора, использующего ByteBuddy
Есть ли способ создать прокси для класса без пустого конструктора, используя ByteBuddy?
Идея состоит в том, чтобы создать прокси для данного конкретного типа, а затем перенаправить все методы в обработчик.
Этот тест демонстрирует сценарий создания прокси для класса без пустого конструктора, и он выдает 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 ответ
Вы звоните subclass(FooEntity.class)
подразумевает, что Byte Buddy неявно имитирует все конструкторы, определенные суперклассом. Вы можете добавить кастом ConstructorStrategy
в качестве второго аргумента, чтобы изменить это поведение.
Однако JVM требует, чтобы любой конструктор в конечном итоге вызывал супер-конструктор, когда ваш прокси-класс предлагает только один с одним конструктором. Учитывая ваш код, вы можете создать прокси, просто предоставив аргумент по умолчанию:
FooEntity newInstance = (FooEntity) dynamicType
.getConstuctor(String.class)
.newInstance(null);
Поле затем устанавливается на null
, В качестве альтернативы вы можете создавать экземпляры классов с помощью библиотеки, такой как Objenesis, которая использует внутренние компоненты JVM для создания экземпляров без каких-либо вызовов конструктора.