zoukankan      html  css  js  c++  java
  • 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);
        }
  • 相关阅读:
    TCP发送数据分包的问题
    利尔达NT90无法烧录固件的问题
    position:fixed 相对于父元素定位
    PHP上传图片到阿里云OSS(图片文件或base64数据)
    python动态加载类并调用
    python 图片验证码识别
    解决python logging 中文乱码问题
    系统中断,电脑卡顿的解决办法
    清理WSL2的磁盘占用
    jqGrid--设置单元格字体颜色
  • 原文地址:https://www.cnblogs.com/zzq-include/p/12061113.html
Copyright © 2011-2022 走看看