Java 如何找到引用方法的第一个声明方法
假设您有一个通用接口和一个实现:Java 如何找到引用方法的第一个声明方法,java,generics,reflection,inheritance,proxy,Java,Generics,Reflection,Inheritance,Proxy,假设您有一个通用接口和一个实现: public interface MyInterface<T> { void foo(T param); } public class MyImplementation<T> implements MyInterface<T> { void foo(T param) { } } 我为扩展接口创建了一个AOP代理,并截获了对进一步声明的方法的调用。由于foo(…)现在在MyExtendedInterface
public interface MyInterface<T> {
void foo(T param);
}
public class MyImplementation<T> implements MyInterface<T> {
void foo(T param) {
}
}
我为扩展接口创建了一个AOP代理,并截获了对进一步声明的方法的调用。由于foo(…)
现在在MyExtendedInterface
中重新声明,我无法通过调用MethodInvocation.procedue()
执行它,因为MyImplementation
的实例只实现MyInterface.foo(…)
而不是MyExtendedInterface.foo(…)
那么,有没有一种方法可以访问最初声明方法的方法呢?关于这个例子,有没有一种方法可以找到foo(Bar param)
最初是在MyInterface
中声明的,并且可以访问Accorriding方法
实例
我已经尝试过扫描基类方法,以根据名称和参数类型进行匹配,但由于出现泛型,所以这不起作用,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));
拦截器几乎扫描方法并对MyExtendedInterface
中声明的所有方法执行JPA查询,但将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.procedure()而是检测最初声明要调用的方法,并在目标上手动调用该方法。整个场景看起来很奇怪。您不能将在
MyExtendedInterface
上声明的AOP应用于MyImplementation
,因为它没有实现它
其次,我不明白为什么定义方法的接口很重要,因为调用方法的是实现
除此之外,您还可以通过
getDeclaredMethods()
获取特定类/接口声明的所有方法。然后,您可以对它们进行迭代,并找到与您的条件(名称)匹配的内容。好的,下面是我提出的解决方案:我知道基类和它的泛型结构(在本例中,T是什么意思)除了MyExtendedInterface
类型MyInterface
到Bar
之外,我还可以扫描基本实现,以查找可能的匹配项,如下所示(伪代码):
在这种情况下,我不需要一个通用的解决方案,这样看起来就可以了。我没有回应,但我认为MyExtendedInterface.class.getMethod(“foo”,Bar.class)应该可以,使用合成标记或桥接标记。这对你有帮助吗?我真的不明白这有什么帮助。我迭代了
MyExtendedInterface
中声明的方法。问题是我无法将它们与“MyImplementation”中声明的完全匹配。代理使用什么?javassist?commons代理?来自Spring AOP,所以简单地说JDK动态代理…我可以。我以编程方式创建代理,并添加一个简单的拦截器,用于拦截每个方法调用。在这个拦截器中,我决定将实际方法调用路由到何处getDeclaredMethods()
是一个选项,但我必须确保重新声明的方法实际上覆盖了MyInterface中的方法。实际上还可以声明一个
foo(Foobar-param)`这样就不会覆盖实际的方法。因此,似乎无法确定一个方法是否覆盖了另一个方法,特别是涉及泛型的方法。你能提供拦截器的代码吗。我不能完全理解您的场景。在原始问题中添加了代理创建代码和拦截器。
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
}
}
for all methods {
skip those with non matching name and parameters length;
for all generic parametertypes {
if typename = T then concrete type has to be Bar
...
}
}