私は過去にReflectionsライブラリを使用して、特定のアノテーションを持つ、または特定のクラスから継承するクラスパス内のクラスをクエリしました。ライブラリはそのような特定のクエリに答えるメソッドをすでに提供しているので、これはReflectionsで非常に簡単に行うことができます。
たとえば、次のコードは、パッケージ内にあるクラス(Reflection.javaクラスのドキュメントから取得した例)を探して、から継承するSomeType
クラスと注釈付きのクラスをクエリする方法を示しています。SomeAnnotation
my.package.prefix
Reflections reflections = new Reflections("my.package.prefix");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);
ただし、現在の問題では、任意のプロパティのセット(たとえば、特定のクラス名+既存の注釈+その他の組み合わせ)を持つクラスを照会する必要があります。これらのプロパティは、私が開発しているライブラリを使用してプログラマーが定義する必要があるため、事前にはわかりません。
ソリューションの一部は、クラスが回答セットに含まれるべきかどうかに答えるブールメソッドを使用してStrategyクラスを定義するようにプログラマーに依頼するようなものになると思います。
たとえば、プログラマーは次のようなインターフェイスを実装する必要があります。
public interface MyStrategy {
public boolean match(Class clazz);
}
したがって、私の質問は、この戦略オブジェクトを取得したら、プログラマーによって定義された戦略クラスに従って一致するクラスのみを保持するクラスをフィルター処理するようにReflectionsライブラリに指示するにはどうすればよいですか?
アップデート:
どうやらフィルタリング部分は最も難しいタスクではありませんが(@MvGの回答に感謝します)、実際にフィルタリングするすべてのクラス(通常はプログラマーによって定義された一連の基本パッケージ内のクラス)を収集します。したがって、アイデアは、すべてのクラスをクエリしてから、次のメソッドでそれらをフィルタリングすることです
ReflectionUtils.getAll(allClasses, predicate)
。
次に、フィルタリングするクラスの初期セットを取得するためにObject
、プログラマーが選択した特定のパッケージ内のすべてのサブタイプを照会してみました。
これに使用したコードの下:
ConfigurationBuilder config = new ConfigurationBuilder();
FilterBuilder fb = new FilterBuilder();
fb.include(FilterBuilder.prefix("my.package.prefix"));
config.filterInputsBy(fb);
config.setUrls(ClasspathHelper.forPackage("my.package.prefix"));
config.setScanners(new SubTypesScanner(false)); //the first argument at the constructor of SubTypesScanner indicates if the Object class should be ignored
Reflections reflections = new Reflections(config);
Set<Class<? extends Object>> unfilteredClasses = reflections.getSubTypesOf(Object.class);
これは最良の(より効率的な)ソリューションですか?
誰かが別のアイデアを持っていますか?前もって感謝します !