您的位置:首页 > 编程语言 > Java开发

Java类自动扫描功能的实现

2015-08-29 13:22 627 查看
我们在使用Spring时可以指定一个名包,Spring可以自动扫描出该包下的所有组件。通过翻阅Spring源码,其实这个功能不难实现。

首先,所有在classpath下的资源(文件),都是可以被
ClassLoader
加载的。我们可以调用它的
getResources()
方法加载类路径下的文件:

public Enumeration<URL> getResources(String name)
throws IOException


这个方法返回一个
Enumeration
对象,以
URL
对象的形式保存了路径
name
下的所有资源。 如果我们传递一个包路径
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
集合

2. 遍历所有
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


完整的实现在github:https://github.com/wanghongfei/pkg-scanner
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java