• 类操作工具类


    package hjp.smart4j.framework.util;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.io.File;
    import java.io.FileFilter;
    import java.net.JarURLConnection;
    import java.net.URL;
    import java.util.Enumeration;
    import java.util.HashSet;
    import java.util.Set;
    import java.util.jar.JarEntry;
    import java.util.jar.JarFile;
    
    /**
     * 类操作工具类
     */
    public final class ClassUtil {
        private static final Logger LOGGER = LoggerFactory.getLogger(ClassUtil.class);
    
        /**
         * 获取类加载器
         */
        public static ClassLoader getClassLoader() {
            return Thread.currentThread().getContextClassLoader();
        }
    
        /**
         * 加载类
         * className为类的全包名
         */
        public static Class<?> loadClass(String className, boolean isInitialized) {
            Class<?> cls;
            try {
                cls = Class.forName(className, isInitialized, getClassLoader());
            } catch (ClassNotFoundException e) {
                LOGGER.error("load class failure", e);
                throw new RuntimeException();
            }
            return cls;
        }
    
        /**
         * 获取指定包名下的所有类
         */
        public static Set<Class<?>> getClassSet(String packageName) {
            Set<Class<?>> classSet = new HashSet<Class<?>>();
            try {
                Enumeration<URL> urls = getClassLoader().getResources(packageName.replace(".", "/"));
                while (urls.hasMoreElements()) {
                    URL url = urls.nextElement();
                    if (url != null) {
                        String protocol = url.getProtocol();//url协议
                        if (protocol.equals("file")) {
                            String packagePath = url.getPath().replaceAll("%20", " ");
                            addClass(classSet, packagePath, packageName);
                        } else if (protocol.equals("jar")) {
                            JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
                            if (jarURLConnection != null) {
                                JarFile jarFile = jarURLConnection.getJarFile();
                                if (jarFile != null) {
                                    Enumeration<JarEntry> jarEntries = jarFile.entries();
                                    while (jarEntries.hasMoreElements()) {
                                        JarEntry jarEntry = jarEntries.nextElement();
                                        String jarEntryName = jarEntry.getName();
                                        if (jarEntryName.endsWith(".class")) {
                                            String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");
                                            doAddClass(classSet, className);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                LOGGER.error("get class set failure", e);
                throw new RuntimeException(e);
            }
            return classSet;
        }
    
        private static void addClass(Set<Class<?>> classSet, String packagePath, String packageName) {
            final File[] files = new File(packagePath).listFiles(new FileFilter() {
                public boolean accept(File file) {
                    //过滤出Class文件或文件夹
                    return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();
                }
            });
            for (File file : files) {
                String fileName = file.getName();
                if (file.isFile()) {
                    //如果是类文件构造类文件全包名
                    String className = fileName.substring(0, fileName.lastIndexOf("."));
                    if (StringUtil.isNotEmpty(packageName)) {
                        className = packageName + "." + className;
                    }
                    doAddClass(classSet, className);//这个方法就是用Class.forName方法得到类,加到classSet集合中
                } else {
                    //如果是文件夹
                    //构造此文件夹相对路径
                    String subPacakgePath = fileName;
                    if (StringUtil.isNotEmpty(subPacakgePath)) {
                        subPacakgePath = packagePath + "/" + subPacakgePath;
                    }
                    //构造此文件夹包名路径
                    String subPacakgeName = fileName;
                    if (StringUtil.isNotEmpty(subPacakgeName)) {
                        subPacakgeName = packageName + "." + subPacakgeName;
                    }
                    //递归加载类
                    addClass(classSet, subPacakgePath, subPacakgeName);
                }
            }
        }
    
        private static void doAddClass(Set<Class<?>> classSet, String className) {
            Class<?> cls = loadClass(className, false);
            classSet.add(cls);
        }
    
    }

    1、通过类加载器,得到指定路径下所有资源,返回Enumeration<URL>集合

    2、类文件要么是以.class结尾的文件,要么是在jar包中以.class结尾的文件

    3、URL 统一资源定位器,遍历Enumeration<URL>集合,分别处理url协议为file或jar的文件

    4、如果是file协议,分两种,一种是文件,另一种是文件夹;得到file协议的每一个class格式文件,分析出该class文件全包名,Class.forName方法得到该类

    5、如果是jar协议,得到jar包内文件,遍历得到class格式文件,分析出该class文件全包名,Class.forName方法得到该类

  • 相关阅读:
    VS Code 调试 Angular 和 TypeScript 的配置
    如何在 ASP.NET Core 中发送邮件
    十二个 ASP.NET Core 例子
    ASP.NET Core MVC 源码学习:详解 Action 的激活
    10 分钟学会Linux常用 bash命令
    ASP.NET Core MVC 源码学习:详解 Action 的匹配
    ASP.NET Core MVC 源码学习:MVC 启动流程详解
    ASP.NET Core MVC 源码学习:Routing 路由
    多叉树查找
    《转》Ubuntu 12.04常用的快捷键
  • 原文地址:https://www.cnblogs.com/hujiapeng/p/5584110.html
Copyright © 2020-2023  润新知