Метод делегирования себе - PullRequest
0 голосов
/ 21 февраля 2020

Я хочу использовать Byte-Buddy для генерации класса, который делегирует методы интерфейса методу, унаследованному от суперкласса.

Два приведенных ниже фрагмента кода делают это:

Class<? extends Object> clazz = new ByteBuddy()
    .subclass(serviceSuperClass)
    .name(className) 
    .implement(serviceInterface)
    .defineField(generalInterceptor, GrandFatherProxy.class, Visibility.PUBLIC)
    .method(isDeclaredBy(serviceInterface))
    .intercept(MethodDelegation.toField(generalInterceptor))
    .make ()
    .load(classLoader)
    .getLoaded();

В этом случае GrandFatherProxy.class является суперклассом данного serviceSuperClass и, следовательно, clazz.

Once Я использовал Reflection для генерации экземпляра clazz, затем я могу установить поле generalInterceptor с экземпляром:

Field field = instance.getClass().getDeclaredField(generalInterceptor);
field.setAccessible(true);
field.set(instance, instance);  // set field on instance to contain instance!

Это работает: Clazz теперь делегирует себя: все методы интерфейса перехватываются @RuntimeType intercept() метод clazz наследуется от GrandFatherProxy.class.

Однако было бы еще элегантнее, если бы я мог явно указать Byte-Buddy для самостоятельного делегирования.

например что-то вроде:

Class<? extends Object> clazz = new ByteBuddy()
    .subclass(serviceSuperClass)
    .name(className) 
    .implement(serviceInterface)
    .method(isDeclaredBy(serviceInterface))
    .intercept(MethodDelegation.toSelf())
    .make ()
    .load(classLoader)
    .getLoaded();

Где toSelf() - мой псевдокод, инструктирующий Byte-Buddy, что сгенерированный класс должен делегировать себя.

Я пропустил способ сделать это? Или это потребует изменения в Byte-Buddy?

1 Ответ

0 голосов
/ 22 февраля 2020

Вы можете обойти это, определив закрытый метод, который возвращает this, а затем использовать MethodDelegation.toMethodReturnOf для этого метода. Чтобы добавить эту функцию, потребуется изменить библиотеку.

...