JAVA 扫描指定路径下所有的jar包,并保存所有实现固定接口的类型

 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);
    }

猜你喜欢

转载自www.cnblogs.com/zzq-include/p/12061113.html