包及jar包掃描
阿新 • • 發佈:2018-11-06
public PackageScanner() { } //掃描包 private void scanFile(File currentFile, String packageName) { //File[] fileList = file.listFiles(); //得到該資料夾下的所有 類+子資料夾的名稱 //此處list應為掃描包下的所有類的nameList,所以不應該有檔名稱 //所以應該加一個檔案過濾器 File[] fileList = currentFile.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if(pathname.isDirectory()) { return true; } return pathname.getName().endsWith(".class"); } }); for(File f : fileList) { //如果是資料夾,遞迴處理 if(f.isDirectory()) { scanFile(f, packageName + "." + f.getName()); } else { String className = packageName + "." + f.getName().replace(".class", ""); try { Class<?> klass = Class.forName(className);//得到類 //可以篩選類 if(klass.isAnnotation()//是註解 || klass.isEnum()//是列舉 || klass.isInterface()//是介面 || klass.isPrimitive()) {//是基本型別 continue; //這些型別我們不需要 所以不處理 } dealClass(klass); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } } //掃描jar包 private void scanJarPackage(URL url) throws IOException { //連線jar檔案的一個入口連線定位 JarURLConnection urlConnection = (JarURLConnection) url.openConnection(); JarFile jarFile = urlConnection.getJarFile();//得到jar檔案 Enumeration<JarEntry> jarEntries = jarFile.entries(); //讀取jar檔案下的內容 while(jarEntries.hasMoreElements()) { JarEntry jarEntry = jarEntries.nextElement(); String jarName = jarEntry.getName(); if (jarEntry.isDirectory() || !jarName.endsWith(".class")) { continue; } String className = jarName.replace(".class", "").replaceAll("/", "."); try { Class<?> klass = Class.forName(className); if (klass.isAnnotation() || klass.isInterface() || klass.isEnum() || klass.isPrimitive()) { continue; } dealClass(klass); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } public void packageScanner(String packageName) { String packageRelativePath = packageName.replace('.', '/'); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); //執行緒.得到當前執行緒.得到類載入器(當前執行緒即這個test,但不能直接用test. , //因為java是多執行緒的,可能不會得到這個test) try { Enumeration<URL> resource = classLoader.getResources(packageRelativePath); //一個列舉型別集合 while(resource.hasMoreElements()) { URL url = resource.nextElement(); if(url.getProtocol().equals("jar")) { scanJarPackage(url); } else { File file = new File(url.toURI()); if(!file.exists()) {//file不存在 continue; } //得到要掃描的包(即資料夾) 此處為classes scanFile(file, packageName); } } } catch (Exception e) { e.printStackTrace(); } } public abstract void dealClass(Class<?> klass); public static void main(String[] args) { String packageName = "com.zty.classes"; //path如果是以 / 開頭,就從classpath中去找 //(classpath是bin目錄或是target的classes目錄) //如果不以/開頭,就以當前類的位置開始找 new PackageScanner(){ @Override public void dealClass(Class<?> klass) { System.out.println(klass.getName()); } }.packageScanner(packageName); }
掃描的包為:
執行結果:
剔除了列舉、介面、註解及基本型別之後的結果。