Предположим, у вас есть универсальный интерфейс и реализация:
public interface MyInterface<T> {
void foo(T param);
}
public class MyImplementation<T> implements MyInterface<T> {
void foo(T param) {
}
}
Эти два типа являются типами инфраструктуры, которые я предоставляю. На следующем шаге я хочу позволить пользователям расширить этот интерфейс, а также переопределить foo(T param)
, чтобы, возможно, снабдить его дополнительными аннотациями.
public interface MyExtendedInterface extends MyInterface<Bar> {
@Override
void foo(Bar param);
// Further declared methods
}
Я создаю прокси-сервер AOP для расширенного интерфейса и особенно перехватываю вызовы к дополнительно объявленным методам. Поскольку foo(…)
теперь объявлено в MyExtendedInterface
, я не могу выполнить его, просто вызвав MethodInvocation.proceed()
, поскольку экземпляр MyImplementation
реализует только MyInterface.foo(…)
, а не MyExtendedInterface.foo(…)
.
Так есть ли способ получить доступ к методу, который объявил метод изначально? Что касается этого примера, есть ли способ узнать, что foo(Bar param)
был первоначально объявлен в MyInterface
, и получить доступ к соответствующему экземпляру Method
?
Я уже пытался отсканировать методы базового класса, чтобы они соответствовали именам и типам параметров, но это не сработало, так как всплывают обобщения, и MyImplementation.getMethod("foo", Bar.class)
явно выбрасывает NoSuchMethodException
. Я уже знаю, что MyExtendedInterface
набирает MyInterface
до Bar
. Так что, если бы я мог создать некое «типизированное представление» на MyImplementation
, мой математический алгоритм мог бы сработать на самом деле.
Дополнительная информация:
Я создаю прокси для MyExtendedInterface
следующим образом:
ProxyFactory factory = new ProxyFactory();
factory.setTarget(new MyImplementation());
factory.setInterfaces(new Class[] { MyExtendedInterface.class });
factory.addInterceptor(new MyInterceptor(MyExtendedInterface.class));
Перехватчик в значительной степени сканирует методы и выполняет запросы JPA для всех методов, объявленных в MyExtendedInterface
, но перенаправляет все вызовы методов методов, объявленных в MyInterface
, на цель прокси. Это работает до тех пор, пока методы из MyInterface
не объявлены как цель, и больше не реализуют ее.
public class MyInterceptor implements MethodInterceptor {
public Object invoke(final MethodInvocation invocation)
throws Throwable {
// handling of query methods
// else
invocation.proceed();
// ^^ works if not redeclared but not if
}
}
Итак, что я хотел бы сделать вместо invocation.proceed () - это определить метод, который первоначально объявил вызываемый , и вызвать его на цели вручную.