Javaクラスの自動スキャン機能の実現
4525 ワード
私たちはSpringを使う時に、一つの名カバンを指定できます。Springはこのカバンの下の全部の部品を自動的にスキャンできます。Springのソースコードを調べることによって、実はこの機能は実現しにくいです。
まず、すべてのclassipathにおけるリソース(ファイル)は、
上記の考え方に基づき、
まず、すべてのclassipathにおけるリソース(ファイル)は、
ClassLoader
によってロードされ得る。getResources()
方法でクラスパスの下のファイルをロードするために呼び出すことができます。public Enumeration<URL> getResources(String name)
throws IOException
この方法は、Enumeration
オブジェクトに戻り、URL
オブジェクトとして経路name
の下のすべてのリソースを保存している。もし私たちが1つのパケットパスcn/fh
を渡すなら、ClassLoader cl = Thread.currentThread().getContextClassLoader();
Enumeration<URL> urls = cl.getResources("cn/fh");
while (urls.hasMoreElements()) {
URL u = urls.nextElement();
System.out.println(u);
System.out.println(u.getProtocol());
System.out.println(u.getPath());
}
以下の出力結果があります。file:/Users/whf/projects/exam/out/production/exam/cn/fh/
file
/Users/whf/projects/exam/out/production/exam/cn/fh/
これはcn/fh
がJARカバンにない結果です。JARパッケージの場合、以下の情報が出力されます。jar:file:/Users/whf/.m2/repository/cn/fh/web-security/2.1.1.RELEASE/web-security-2.1.1.RELEASE.jar!/cn/fh/
jar
file:/Users/whf/.m2/repository/cn/fh/web-security/2.1.1.RELEASE/web-security-2.1.1.RELEASE.jar!/cn/fh/
これにより、スキャン機能の考えを得ることができる。1.ClassLoader#getResources()
方法を呼び出し、URL
のセットに戻ってきた。URL
のすべてのオブジェクトを巡回した。3.ファイルであれば、ファイルI/O操作により、このディレクトリのすべての*.class
ファイルを巡回し、クラス名を抽出する。4.Jarパケットであれば、JarパケットI/O動作によりJarパケットを巡回し、パケット内のすべての*.class
ファイルを抽出する。上記の考え方に基づき、
PkgScanner
類を書いて、次のような使い方を提供します。PkgScanner scanner = new PkgScanner("cn.fh.pkgscanner");
List<String> list = scanner.scan();
list.forEach( f -> System.out.println(f));
出力:cn.fh.pkgscanner.PathUtils
cn.fh.pkgscanner.PkgScanner
cn.fh.pkgscanner.ResourceType
完全な実現はgithbにあります。https://github.com/wanghongfei/pkg-scanner