component-scan
開発中の Android フレームワークに、Spring の に似たパッケージ スキャン機能を実装しようとしています。基本的に、基本パッケージを指定して、特定の注釈を持つcom.foo.bar
すべてのインスタンスを取得できるようにしたいと考えています。Class
すべてのコンポーネントをフレームワークに登録する必要はありません。自動スキャンの目的が損なわれるからです。
私の調査によると、Java では、リフレクションを使用してパッケージ名を指定してリソースを取得することはできないようです。ただし、簡単にReflections フレームワークを調べたところ、Android 互換の同等のものがあるかどうか疑問に思っています。そうでない場合は、私がやりたいことを達成するための少し分かりにくい方法があるかもしれません。
Spring のソースを少し調べて、彼らがこれをどのように達成したかを確認しましたが、彼らがしていることは Dalvik ランタイム内で機能するとは思いません。
アップデート
現在、以下のコードは、特定の注釈を含むすべてのクラスを取得するために私ができる最善の方法ですが、率直に言って、それはかなり貧弱な解決策です。ClassLoader
さらに、すべてのアプリケーション クラスをスキャン (およびロード) することについて、非常に危険な仮定を立てています。
public Set<Class<?>> getClassesWithAnnotation(Class<? extends Annotation> annotation) {
Set<Class<?>> classes = new HashSet<Class<?>>();
Field dexField = PathClassLoader.class.getDeclaredField("mDexs");
dexField.setAccessible(true);
PathClassLoader classLoader = (PathClassLoader) Thread.currentThread().getContextClassLoader();
DexFile[] dexs = (DexFile[]) dexField.get(classLoader);
for (DexFile dex : dexs) {
Enumeration<String> entries = dex.entries();
while (entries.hasMoreElements()) {
String entry = entries.nextElement();
Class<?> entryClass = dex.loadClass(entry, classLoader);
if (entryClass != null && entryClass.isAnnotationPresent(annotation)) {
classes.add(entryClass);
}
}
}
return classes;
}