今天学到了Spring通过一个基包来扫描下面的所有的类,我就再想这到底是怎么样实现的,为何spring这么的神奇,给一个基包就能得到它下面的所有的类名(包括子包),自己琢磨了一下,完成了这个功能,也算是给自己留下一点笔记,也为那些迷惑的程序员来查阅。
PS:这些东西其实还是蛮有意思的,有时觉得什么什么好像很神奇,当自己琢磨清楚以后也不过如此.
package test;
import java.io.File;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
public class ClassScan {
/**
* 扫描给定的基包下的所有的类(包括子包)。
* @param basePackageName 基包的名称
* @return 所有在基包下的类的全名
*/
public static Set<String> scanBasePackage(String basePackageName){
String packageDirName = basePackageName.replace(".", "/");
URL url = Thread.currentThread().getContextClassLoader().getResource(packageDirName);
System.out.println(url);
File targetFile = new File(url.getFile());
if(!targetFile.exists() || targetFile.isFile()){
throw new RuntimeException(basePackageName + "不是一个包名或者该包名不存在");
}
Set<String> classNames = new HashSet<String>();
getAllClass(targetFile, basePackageName, classNames);
return classNames;
}
/**
* 得到所有在parentFile目录下的class文件名称
* @param parentFile
* @param classNames
* @param basePackageName
*/
private static void getAllClass(File parentFile, String basePackageName, Set<String> classNames){
File[] files = parentFile.listFiles();
for(File file : files){
String path = file.getPath();
if(file.isFile()){
if(path.endsWith(".class")){
classNames.add(
basePackageName + "." +
path.substring(
path.lastIndexOf('\\') + 1, path.lastIndexOf('.')
)
);
}
}else{
basePackageName = basePackageName + path.substring(path.lastIndexOf('\\') + 1);
getAllClass(file, basePackageName, classNames);
}
}
}
}
下面是测试和运行结果:
public static void main(String[] args) {
String basePackageName = "cn.zq.spring.di.anotation";
Set<String> classNames = scanBasePackage(basePackageName);
System.out.println(classNames);
}
[cn.zq.spring.di.anotationscan.PersonTest, cn.zq.spring.di.anotationscan.Student, cn.zq.spring.di.anotationscan.Person, cn.zq.spring.di.anotation.PersonTest, cn.zq.spring.di.anotation.Person]