Suppose you have a generic interface and an implementation:
public interface MyInterface<T> {
void foo(T param);
}
public class MyImplementation<T> implements MyInterface<T> {
void foo(T param) {
}
}
These two types are framework types I provide. In the next step I want allow users to extend that interface as well as redeclare foo(T param) to maybe equip it with further annotations.
public interface MyExtendedInterface extends MyInterface<Bar> {
@Override
void foo(Bar param);
// Further declared methods
}
I create an AOP proxy for the extended interface and intercept especially the calls to furtherly declared methods. As foo(…) is now redeclared in MyExtendedInterface I cannot execute it by simply invoking MethodInvocation.proceed() as the instance of MyImplementation only implements MyInterface.foo(…) and not MyExtendedInterface.foo(…).
So is there a way to get access to the method that declared a method initially? Regarding this example is there a way to find out that foo(Bar param) was declared in MyInterface originally and get access to the accoriding Method instance?
I already tried to scan base class methods to match by name and parameter types but that doesn’t work out as generics pop in and MyImplementation.getMethod("foo", Bar.class) obviously throws a NoSuchMethodException. I already know that MyExtendedInterface types MyInterface to Bar. So If I could create some kind of “typed view” on MyImplementation my math algorithm could work out actually.
Additional info:
I create the proxy for the MyExtendedInterface as follows:
ProxyFactory factory = new ProxyFactory();
factory.setTarget(new MyImplementation());
factory.setInterfaces(new Class[] { MyExtendedInterface.class });
factory.addInterceptor(new MyInterceptor(MyExtendedInterface.class));
The interceptor pretty much scans the methods and executes JPA queries for all methods declared in MyExtendedInterface but routes all method invocations of methods declared in MyInterface to the proxy target. This works as long as methods from MyInterface are not redeclared as the target then doesn’t implement it anymore.
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
}
}
So what I would like to do instead of invocation.proceed() is detect the method that originally declared the one being invoked and invoke that on the target manually.
Okay, here’s the solution I came up with: As I know the base class and it generics structure (what T means in this case) as well as
MyExtendedInterfacetypesMyInterfacetoBarI can scan the base implementation for possible matches as follows (pseudocode):I don’t need a generic solution in this case so that seems to work.