Javaクラスの自動スキャン機能の実現

4525 ワード

私たちはSpringを使う時に、一つの名カバンを指定できます。Springはこのカバンの下の全部の部品を自動的にスキャンできます。Springのソースコードを調べることによって、実はこの機能は実現しにくいです。
まず、すべての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