【发布时间】:2010-05-10 17:31:46
【问题描述】:
假设你有一个通用接口和一个实现:
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));
拦截器几乎会扫描方法并对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.proceed() 而是检测最初声明被调用的方法并在目标上手动调用它。
【问题讨论】:
-
我没有回应,但我认为 MyExtendedInterface.class.getMethod("foo", Bar.class) 应该没问题,带有合成或桥标记。这对你有帮助吗?
-
我真的不明白这会有什么帮助。我遍历
MyExtendedInterface的声明方法。问题是我无法将它们与 `MyImplementation 中声明的完全匹配。 -
你用什么做代理?程序员?公共代理?
-
这是来自 Spring AOP,所以简单来说就是 JDK 动态代理...
标签: java generics reflection inheritance proxy