java通過反射的類掃描工具類,通過遍歷類的字節碼,找到目標文件,通過反射實例化,目標類,可以通過接口和注解兩種方式進行掃描。 package com.csnt.scdp.bizmodules.modules.util; import java.io.File; import java.io.IOException; import java.net.JarURLConnection; import java.net.URL; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Objects; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.stream.Collectors; /** * @Description: 類加載工具類,用來掃描各種各樣你幻想中的。。 * * @author qcsy * @Copyright qcsy studio * @date 2020/07/31. */ public class ClassUtil { /** * 類名后綴 */ private static final String class_suffix=".class"; /** * 根據類接口查到所有的class * @param clazz 接口文件 * @return class */ public static <T> List<Class<T>> getAllClassByInterface(Class<T> clazz) { List<Class<T>> list = new ArrayList<>(); try { List<Class> allClass = getAllClass(clazz.getPackage().getName()); /** * 循環判斷路徑下的所有類是否實現了指定的接口 並且排除接口類自己 */ for (int i = 0; i < allClass.size(); i++) { if (clazz.isAssignableFrom(allClass.get(i))) { if (!clazz.equals(allClass.get(i))) { // 自身並不加進去 list.add(allClass.get(i)); } } } } catch (Exception e) { throw new RuntimeException(e); } return list; } /** * 根據類接口查到所有的class * @param clazz 接口文件 * @return class */ public static List<Class> getAllClassByAnnotation(Class clazz) { try { List<Class> allClass = getAllClass(clazz.getPackage().getName()); return allClass.stream().filter((a)->{return a.isAnnotationPresent(clazz);}).collect(Collectors.toList()); } catch (Exception e) { throw new RuntimeException(e); } } /** * 根據類接口查到所有的class(指定包名) * @param clazz 接口文件 * @return class */ public static List<Class> getAllClassByAnnotation(Class clazz,String packageName) { try { List<Class> allClass = getAllClass(packageName); return allClass.stream().filter((a)->{return a.isAnnotationPresent(clazz);}).collect(Collectors.toList()); } catch (Exception e) { throw new RuntimeException(e); } } /** * 從一個指定路徑下查找所有的類 * * @param packagename */ private static List<Class> getAllClass(String packagename) { List<String> classNameList = getClassPathsByPackage(packagename); List<Class> list=classNameList.stream().map((b)->{ try { return Class.forName(b); } catch (Throwable e) { return null; } }).filter(Objects::nonNull).distinct().collect(Collectors.toList()); return list; } /** * 獲取某包下所有類 * @param packageName 包名 * @return 類的完整名稱 */ public static List<String> getClassPathsByPackage(String packageName) { List<String> fileNames = null; ClassLoader loader = Thread.currentThread().getContextClassLoader(); String packagePath = packageName.replace(".", "/"); URL url = loader.getResource(packagePath); if (url != null) { String type = url.getProtocol(); if (type.equals("file")) { String fileSearchPath = url.getPath(); fileSearchPath = fileSearchPath.substring(0,fileSearchPath.indexOf("/classes")); fileNames = getClassPathsByFile(fileSearchPath); } else if (type.equals("jar")) { try{ JarURLConnection jarURLConnection = (JarURLConnection)url.openConnection(); JarFile jarFile = jarURLConnection.getJarFile(); fileNames = getClassPathsByJar(jarFile); }catch (IOException e){ throw new RuntimeException("open Package URL failed:"+e.getMessage()); } }else{ throw new RuntimeException("file system not support! cannot load MsgProcessor!"); } } return fileNames; } /** * 從項目文件獲取某包下所有類 * @param filePath 文件路徑 * @return 類的完整名稱 */ private static List<String> getClassPathsByFile(String filePath) { List<String> classPaths = new ArrayList<String>(); try { Files.walkFileTree(Paths.get(new File(filePath).getAbsolutePath()), new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { String filePath=file.toFile().getPath(); if (filePath.endsWith(class_suffix)) { filePath = filePath.substring(filePath.indexOf(File.separator+"classes") + 9, filePath.lastIndexOf(".")); filePath = filePath.replace(File.separator, ".").replace("/",".").replace("\\","."); classPaths.add(filePath); } return super.visitFile(file, attrs); } }); } catch (Exception e) { throw new RuntimeException("walk files error!",e); } return classPaths; } /** * 從jar獲取某包下所有類 * @return 類的完整名稱 */ private static List<String> getClassPathsByJar(JarFile jarFile) { List<String> myClassName = new ArrayList<String>(); try { Enumeration<JarEntry> entrys = jarFile.entries(); while (entrys.hasMoreElements()) { JarEntry jarEntry = entrys.nextElement(); String entryName = jarEntry.getName(); if (entryName.endsWith(class_suffix)) { entryName = entryName.replace(File.separator, ".").replace("/",".").replace("\\",".").substring(0, entryName.lastIndexOf(".")); myClassName.add(entryName); } } } catch (Exception e) { throw new RuntimeException("發生異常:"+e.getMessage()); } return myClassName; } }