1 packagecom.test.package_scanner.core;2
3 importjava.io.File;4 importjava.io.FileFilter;5 importjava.io.IOException;6 importjava.net.JarURLConnection;7 importjava.net.URISyntaxException;8 importjava.net.URL;9 importjava.util.Enumeration;10 importjava.util.jar.JarEntry;11
12 public abstract classPackageScanner {13
14 publicPackageScanner() {15 }16
17 //scanPackage方法的重载
18 public void scanPackage(Class>klass) {19 scanPackage(klass.getPackage().getName());20 }21
22 public voidscanPackage(String packageName) {23 //将包名称转换为路径名称的形式
24 String packagePath = packageName.replace(".", "/");25
26 try{27 //由类加载器得到URL的枚举
28 Enumeration resources =Thread.currentThread()29 .getContextClassLoader()30 .getResources(packagePath);31
32 while(resources.hasMoreElements()) {33 URL url =resources.nextElement();34
35 //处理jar包
36 if (url.getProtocol().equals("jar")) {37 parse(url);38 } else{39 File file = newFile(url.toURI());40
41 if(file.exists()) {42 //处理普通包
43 parse(file, packageName);44 }45 }46 }47 } catch(IOException e) {48 e.printStackTrace();49 } catch(URISyntaxException e) {50 e.printStackTrace();51 }52 }53 //抽象方法,由用户自行处理扫描到的类
54 public abstract void dealClass(Class>klass);55
56 //jar包的扫描
57 private void parse(URL url) throwsIOException {58 Enumeration jarEntries =((JarURLConnection) url.openConnection())59 .getJarFile().entries();60
61 while(jarEntries.hasMoreElements()) {62 JarEntry jarEntry =jarEntries.nextElement();63 String jarName =jarEntry.getName();64
65 if (!jarEntry.isDirectory() && jarName.endsWith(".class")) {66 //将文件路径名转换为包名称的形式
67 dealClassName(jarName.replace("/", ".").replace(".class", ""));68 }69 }70 }71
72 //普通包的扫描
73 private voidparse(File curFile, String packageName) {74 File[] fileList = curFile.listFiles(newFileFilter() {75 //筛选文件夹和class文件,其余文件不处理
76 @Override77 public booleanaccept(File pathname) {78 return pathname.isDirectory() || pathname.getName().endsWith(".class");79 }80 });81
82 //目录就是一颗树,对树进行递归,找到class文件
83 for(File file : fileList) {84 String fileName =file.getName();85 if(file.isDirectory()) {86 parse(file, packageName + "." +fileName);87 } else{88 String className = packageName + "." + fileName.replace(".class", "");89 dealClassName(className);90 }91 }92 }93
94 //将找到的class文件生成类对象
95 private voiddealClassName(String className) {96 try{97 Class> klass =Class.forName(className);98
99 //注解、接口、枚举、原始类型不做处理
100 if (!klass.isAnnotation()101 && !klass.isInterface()102 && !klass.isEnum()103 && !klass.isPrimitive()) {104 dealClass(klass);105 }106 } catch(ClassNotFoundException e) {107 e.printStackTrace();108 }109 }110
111 }