Java从指定目录下加载class文件

如果需要从 /Users/xxx/IdeaProjects/xxx-demo/xxx-business-core/target/classes 目录下加载编译好的类,需要先递归出所有的class文件,然后load到JVM

public static Set<Class<?>> loadClasses(String rootClassPath) throws Exception {
    Set<Class<?>> classSet = Sets.newHashSet();
    // 设置class文件所在根路径
    File clazzPath = new File(rootClassPath);

    // 记录加载.class文件的数量
    int clazzCount = 0;

    if (clazzPath.exists() && clazzPath.isDirectory()) {
        // 获取路径长度
        int clazzPathLen = clazzPath.getAbsolutePath().length() + 1;

        Stack<File> stack = new Stack<>();
        stack.push(clazzPath);

        // 遍历类路径
        while (!stack.isEmpty()) {
            File path = stack.pop();
            File[] classFiles = path.listFiles(new FileFilter() {
                public boolean accept(File pathname) {
                    //只加载class文件
                    return pathname.isDirectory() || pathname.getName().endsWith(".class");
                }
            });
            if (classFiles == null) {
                break;
            }
            for (File subFile : classFiles) {
                if (subFile.isDirectory()) {
                    stack.push(subFile);
                } else {
                    if (clazzCount++ == 0) {
                        Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
                        boolean accessible = method.isAccessible();
                        try {
                            if (!accessible) {
                                method.setAccessible(true);
                            }
                            // 设置类加载器
                            URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
                            // 将当前类路径加入到类加载器中
                            method.invoke(classLoader, clazzPath.toURI().toURL());
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            method.setAccessible(accessible);
                        }
                    }
                    // 文件名称
                    String className = subFile.getAbsolutePath();
                    className = className.substring(clazzPathLen, className.length() - 6);
                    //将/替换成. 得到全路径类名
                    className = className.replace(File.separatorChar, '.');
                    // 加载Class类
                    Class<?> aClass = Class.forName(className);
                    classSet.add(aClass);
                    System.out.println("读取应用程序类文件[class={" + className + "}]");
                }
            }
        }
    }
    return classSet;
}
posted @ 2019-11-23 16:24  商商-77  阅读(3881)  评论(0编辑  收藏  举报