private static Map<String, Object> loadAllJarFromAbsolute(String directoryPath) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException { File directory = new File(directoryPath); // 判断是否为文件夹,如果是文件,直接用单个jar解析的方法去解析 if (!directory.isDirectory()) { // 添加jar扫描路径 addUrl(directory); return loadJarFromAbsolute(directoryPath); } // 如果是文件夹,则需要循环加载当前文件夹下面的所有jar Map<String, Object> clazzMap = new HashMap<>(16); File[] jars = directory.listFiles(); if (jars != null && jars.length > 0) { List<String> jarPath = new LinkedList<>(); for (File file : jars) { String fPath = file.getPath(); // 只加载jar if (fPath.endsWith(".jar")) { addUrl(file); jarPath.add(fPath); } } if (jarPath.size() > 0) { for (String path : jarPath) { clazzMap.putAll(loadJarFromAbsolute(path)); } } } return clazzMap; } private static Map<String, Object> loadJarFromAbsolute(String path) throws IOException { JarFile jar = new JarFile(path); Enumeration<JarEntry> entryEnumeration = jar.entries(); Map<String, Object> clazzMap = new HashMap<>(32); while (entryEnumeration.hasMoreElements()) { JarEntry entry = entryEnumeration.nextElement(); // 先获取类的名称,符合条件之后再做处理,避免处理不符合条件的类 String clazzName = entry.getName(); if (clazzName.endsWith(".class")) { // 去掉文件名的后缀 clazzName = clazzName.substring(0, clazzName.length() - 6); // 替换分隔符 clazzName = clazzName.replace("/", "."); // 加载类,如果失败直接跳过 try { Class<?> clazz = Class.forName(clazzName); Class superClass = clazz.getSuperclass(); if (superClass.equals(ComponentExtend.class)) { Object o = clazz.newInstance(); Method fieldExtendComponentId = clazz.getMethod("extendComponentId"); String id = (String) fieldExtendComponentId.invoke(o); clazzMap.put(id, o); } } catch (Throwable e) { // 这里可能出现有些类是依赖不全的,直接跳过,不做处理,也没法做处理 } } } return clazzMap; } private static void addUrl(File jarPath) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, MalformedURLException { URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); if (!method.isAccessible()) { method.setAccessible(true); } URL url = jarPath.toURI().toURL(); // 把当前jar的路径加入到类加载器需要扫描的路径 method.invoke(classLoader, url); }