• Java 包扫描器


    包扫描器

    获取一个包下的所有类,然后使用默认的类加载器加载到内存中

        public static List<Class<?>> scanByPackage(String packageName) throws IOException, URISyntaxException {
            //我们传入的包名都是 "com.stdpain.xx" 这种的需要替换成 "com/stdpain/xx"
            String packagePath = packageName.replace(".", "/");
            //获取当前类加载器
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            List<Class<?>> classes = new ArrayList<>();
            Enumeration<URL> resources = classLoader.getResources(packagePath);
            while (resources.hasMoreElements()) {
                //获取 url
                URL url = resources.nextElement();
                //判断url是不是一个 jar:// 类型的url 不同的url需要有不同的处理方式,我们默认只有文件系统和jar
                if (url.getProtocol().equals("jar")) {
                    //handle jar Package
                    System.out.println(url);
                    List<Class<?>> scanedClasses = packageJarScan(url);
                    classes.addAll(scanedClasses);
                } else {
                    File file = new File(url.toURI());
                    if (!file.exists()) {
                        System.out.println("file not exists = " + file.getAbsolutePath());
                        continue;
                    }
                    System.out.println("scan:" + file.getAbsolutePath());
                    //handle file package
                    List<Class<?>> scanedClasses = packageScan(file, packageName);
                    classes.addAll(scanedClasses);
                }
            }
            return classes;
        }
    

    Jar 处理

        public static List<Class<?>> packageJarScan(URL url) throws IOException {
            //强制类型转换
            JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
            JarFile jarFile = jarURLConnection.getJarFile();
            Enumeration<JarEntry> jarEntries = jarFile.entries();
            List<Class<?>> classes = new ArrayList<>();
            //遍历判断
            while (jarEntries.hasMoreElements()) {
                JarEntry jarEntry = jarEntries.nextElement();
                String jarName = jarEntry.getName();
                if (jarEntry.isDirectory() || !jarName.endsWith(".class")) {
                    continue;
                }
                String className = jarName.replace(".class", "").replace("/", ".");
                try {
                    System.out.println(className);
                    Class<?> clazz = Class.forName(className);
                    classes.add(clazz);
                    System.out.println(className + "->load:success");
                } catch (ClassNotFoundException e) {
    //                e.printStackTrace();
                    System.out.println("e.getMessage() = " + e.getMessage());
                }
            }
            return classes;
        }
    

    文件系统直接递归处理目录就可以

        public static List<Class<?>> packageScan(File curFile, String packageName) {
            ArrayList<Class<?>> classes = new ArrayList<>();
            if (!curFile.isDirectory()) {
                return classes;
            }
            File[] files = curFile.listFiles();
            for (File file : files) {
                if (file.isFile() && file.getName().endsWith(".class")) {
                    String fileName = file.getName().replace(".class", "");
                    String className = packageName + "." + fileName;
                    try {
                        Class<?> clazz = Class.forName(className);
                        classes.add(clazz);
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                } else if (file.isDirectory()) {
                    //如果是个目录那么就递归处理目录
                    classes.addAll(packageScan(file, packageName + "." + file.getName()));
                }
            }
            return classes;
        }
    

    包扫描器有什么用

    Spring 中通过注解配置 就是通过包扫描器下每个class是否包含某些注解

  • 相关阅读:
    LOJ6435 「PKUSC2018」星际穿越
    LOJ6433 「PKUSC2018」最大前缀和
    LOJ2541 「PKUWC2018」猎人杀
    LOJ2545 「JXOI2018」守卫
    LOJ2290 「THUWC 2017」随机二分图
    CF1007B Pave the Parallelepiped
    【学习笔记】卡特兰数
    Linux系统命令“su
    免密
    Window操作系统下的SSL证书管理
  • 原文地址:https://www.cnblogs.com/stdpain/p/11240690.html
Copyright © 2020-2023  润新知