リフレクションを使用して、JSR-330 アノテーション付きクラスの依存関係を判別するために何らかの処理を行う必要があります。
Spring、Guice、PicoContainer など、JSR-330 準拠のすべての IoC コンテナーを十分に認識しています。ただし、依存関係を解決して注入するのではなく、依存関係を特定する必要があります。
つまり、少なくともリフレクション クラスの「解析」に関しては、JSR-330 実装を実装する必要があるということです。
JSR-330 仕様には、実装するのが少し面倒だと思う部分が 1 つあります。
@Inject でアノテーションが付けられた別のメソッドをオーバーライドする @Inject でアノテーションが付けられたメソッドは、インスタンスごとに注入リクエストごとに 1 回だけ注入されます。@Inject でアノテーションが付けられたメソッドをオーバーライドする @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 グアバのような述語については、次のことを確認します。
- クラスを定義するメソッドは isAssignableFrom 関係にあります
- メソッド名が同じ
- メソッドの仮パラメータは同じです
結果の複雑さは、階層内のメソッドの数に関して O(n^2) になります。
それを達成するためのより簡単で効率的な方法、またはそのような機能を備えたライブラリがあるかどうか疑問に思っていました。Guava と Apache Commons の両方で失敗しました...