Определить метод, вызов и перехватчик и делегат для цели с ByteBuddy? - PullRequest
0 голосов
/ 24 октября 2019

У меня есть объект service, который имеет несколько методов, один из этих методов - foo(arg1, arg2).

Хотите создать новый класс-обертку, который:

  • имеет одинметод _foo с одним дополнительным аргументом
  • делегирование _foo выполнение перехватчику, возврат игнорируется
  • наконец, делегировать вызов цели foo на service.

Почему-то я не могу это сделать:

final List<Class<?>> parameters =
    Arrays.stream(fooMethod.getParameters())
          .map(Parameter::getType)
          .collect(Collectors.toList());

    parameters.add(AdditionalParameter.class);


final DynamicType.Unloaded unloadedType = new ByteBuddy()
    .subclass(Object.class)
    .implement(interfaceType)
    .name(service.getClass().getSimpleName() + "Dynamic")
    .defineMethod(
        "_" + methodName,
        resolveReturnType(fooMethod),
        Modifier.PUBLIC)
    .withParameters(parameters)
    .intercept(to(fooInterceptor).andThen(
        MethodCall.invoke(fooMethod).on(service)
    ))
    .make();

fooInterceptor - это InvocatiomHandler экземпляр:

public class FooInterceptor implements InvocationHandler {
public Object invoke(
    @This final Object proxy,
    @Origin final Method method.
    @AllArguments final Object[] args) {
    ...
    }
}

Исключениеговорит, что мой fooService "не принимает 0 аргументов".

Могу ли я позвонить service.foo() от перехватчика - но без использования отражения? Я не могу этого сделать (но еще не играл с этой частью).

Справка? ?

РЕДАКТИРОВАТЬ: я не контролирую, какие методы в service, поэтомуЯ не могу просто использовать to(service) с перехватом вызова;может быть случай, когда ByteBuddy не сможет найти соответствующий метод.

EDIT2: Если я могу просто «сказать» ByteBuddy имя целевого метода для привязки, это было бы здорово. Тогда я мог бы использовать to(service) с заданной подсказкой.

1 Ответ

1 голос
/ 27 октября 2019

Можно указать сопоставление для MethodDelegation, чтобы сузить методы, которые необходимо учитывать:

MethodDelegation.withDefaultConfiguration().filter(...).to(...)

Что касается вашего MethodCall, вам нужно указать, какие аргументы включить, foo занимает двааргументы. Поскольку ваши исходные аргументы кажутся эквивалентными, вы можете установить:

MethodCall.invoke(fooMethod).on(service).withAllArguments();
...