我需要做一些处理以确定 JSR-330 注释类的依赖关系,使用反射。
我完全了解所有符合 JSR-330 的 IoC 容器,例如 Spring、Guice 或 PicoContainer。但是,我需要的不是解析和注入(inject)依赖项,而是识别它们。
这基本上意味着我需要实现 JSR-330 实现,至少在涉及反射类“解析”时。
我发现 JSR-330 规范的一部分实现起来有点麻烦:
A method annotated with @Inject that overrides another method annotated with @Inject will only be injected once per injection request per instance. A method with no @Inject annotation that overrides a method annotated with @Inject will not be injected.
这意味着子类可以重新定义其基类的 Autowiring 契约,以及 Hook 到注入(inject)流中(通过多态性)。
我的问题来了:给定一个类层次结构,是否有一种简单的方法来检查层次结构中某些部分的方法是否被层次结构中更下层的方法覆盖?
在我的例子中,最简单的方法是从层次结构的叶递归:
private List<Method> getInjectableMethods(final Class<?> clazz) {
// recursive stop condition
if(clazz == null) {
return emptyList();
}
// recursively get injectable methods from superclass
final List<Method> allInjectableMethods = newLinkedList(getInjectableMethods(clazz.getSuperclass()));
final List<Method> injectableMethods = newArrayList();
// any overridden method will be present in the final list only if it is injectable in clazz
for (final Method method : clazz.getDeclaredMethods()) {
removeIf(allInjectableMethods, Methods.Predicates.overriddenBy(method));
if (isInjectable(method)) {
injectableMethods.add(method);
}
}
allInjectableMethods.addAll(injectableMethods);
return allInjectableMethods;
}
至于 overriddenBy-like Predicate,我会检查:
- 定义类的方法在 isAssignableFrom 关系中
- 方法名称相同
- 方法形参相同
关于层次结构中方法的数量,由此产生的复杂度为 O(n^2)。
我想知道是否有更简单或更有效的方法来实现它,或者是否有任何具有此类功能的库。我在 Guava 和 Apache Commons 中都没有成功...
最佳答案
不幸的是,类图只能在根方向导航——所以除了检查特定类加载器可用的所有类之外,没有办法找到所有派生类。 IoC 容器没有这个问题,因为它们总是知 Prop 体的实现 (它是配置的一部分)
继承树通常由 IDE 构建,但 AFAIUK 它们对所有可用的源/类使用强行索引(您可以查看 InteliiJ IDEA 社区版本的源以获取线索)
关于Java:如何使用反射检查方法是否被覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9672839/