![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 package javax.servlet.util; 2 3 import java.io.File; 4 import java.io.FileFilter; 5 import java.io.FileNotFoundException; 6 import java.io.IOException; 7 import java.net.URL; 8 import java.net.URLDecoder; 9 import java.util.Enumeration; 10 import java.util.Iterator; 11 import java.util.LinkedHashSet; 12 import java.util.Set; 13 14 15 public class PackageScanUtils 16 { 17 18 /** 19 * 获取class集合 20 * @param packName 包名 21 * @param scanSubdirectory 扫描子目录 22 * @return 23 */ 24 public static Set<Class<?>> getClasses(String packName,boolean scanSubdirectory) 25 { 26 27 Set<Class<?>> classes = new LinkedHashSet<Class<?>>(); // 装载class集合 28 String packageName = packName; // 获取包的名字 并进行替换 29 String packageUrlName = packageName.replace('.', '/'); 30 Enumeration<URL> urls; // 定义一个枚举的集合 并进行循环来处理这个目录下的class 31 try 32 { 33 urls = Thread.currentThread().getContextClassLoader().getResources(packageUrlName); 34 35 // 循环迭代下去 36 while (urls.hasMoreElements()) 37 { 38 39 URL url = urls.nextElement(); // 获取下一个元素 40 41 String protocol = url.getProtocol(); // 得到协议的名称,比如http、file 42 43 if ("file".equals(protocol)) 44 { // 如果是以文件的形式保存在服务器上 45 46 String filePath = URLDecoder.decode(url.getFile(), "UTF-8"); // 获取包的物理路径 47 // 以文件的方式扫描整个包下的文件 并添加到集合中 48 findClassesInPackageByFile(packageName, filePath, scanSubdirectory, classes); 49 } 50 } 51 } catch (IOException e) 52 { 53 e.printStackTrace(); 54 } 55 56 return classes; 57 } 58 59 /** 60 * 以文件的方式扫描整个包下的文件 并添加到集合中 61 * @param packageName 包名 62 * @param packagePath 包路径 63 * @param scanSubdirectory 是否扫描子目录 64 * @param classes class集合 65 * @throws FileNotFoundException 66 */ 67 public static void findClassesInPackageByFile(String packageName, String packagePath, final boolean scanSubdirectory, Set<Class<?>> classes) throws FileNotFoundException 68 { 69 70 File dir = new File(packagePath); // 获取此包的目录 建立一个File 71 File[] dirfiles = dir.listFiles(new FileFilter() 72 { // 如果存在 就获取包下的所有文件 包括目录 73 74 public boolean accept(File file) 75 { // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件) 76 return (scanSubdirectory && file.isDirectory()) || (file.getName().endsWith(".class")); 77 } 78 }); 79 80 for (File file : dirfiles) 81 { // 循环所有文件 82 83 if (file.isDirectory()) 84 { // 如果是目录 则继续扫描 85 findClassesInPackageByFile(packageName==""? file.getName():packageName + "." + file.getName(), file.getAbsolutePath(), scanSubdirectory, classes); 86 } else 87 { // 如果是java类文件 去掉后面的.class 只留下类名 88 89 String className = file.getName().substring(0, file.getName().length() - 6); 90 try 91 { 92 if("".equals(packageName)){ 93 classes.add(Thread.currentThread().getContextClassLoader().loadClass(className)); 94 }else{ 95 classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className)); 96 } 97 } catch (ClassNotFoundException e) 98 { 99 e.printStackTrace(); 100 } 101 } 102 } 103 } 104 105 public static void main(String[] args) 106 { 107 Set<Class<?>> clas=PackageScanUtils.getClasses("cn.javax",true); 108 Iterator<Class<?>>cla=clas.iterator(); 109 while(cla.hasNext()){ 110 /*Annotation[]ann=cla.next().getAnnotations(); 111 for(Annotation a:ann){ 112 if(a instanceof WebServlet){ 113 System.out.println(((WebServlet) a).value()); 114 } 115 }*/ 116 System.out.println(cla.next().getName()); 117 } 118 } 119 }
运行