扫描jar包中的resource文件

 /**
     * 扫描包,过滤出所有包含指定注解的类, 然后将类中所有指定注解属性替换。
     *
     * @param
     */
    public List<Class> getClassesForAnnotation(String scanPackage, Class annotationClass) {
        //需要扫描的package
        List<Class> classes = new ArrayList<Class>();
        List<String> classNames = new ArrayList<>();
        try {
            classNames = doScenner(scanPackage);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        for (String className : classNames) {
            try {
                Class clazz = Class.forName(className);
                Annotation a = clazz.getAnnotation(annotationClass);
                if (a != null) {
                    classes.add(clazz);
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

        }
        return classes;
    }


    /**
     * 扫描包下所有的class路径集合
     *
     * @param scanPackage
     */
    public List<String> doScenner(String scanPackage) throws UnsupportedEncodingException {
        List<String> classNames = new ArrayList<String>();
        // System.getProperty("user.dir"); //项目根目录
        //扫描scanPachage 的class
        String url = this.getClass().getClassLoader().getResource(scanPackage
                .replaceAll("\\.", "/")).getPath();

        String packagePath = java.net.URLDecoder.decode(url, "utf-8");
        File classPath = new File(packagePath);
        for (File file : classPath.listFiles()) {
            if (file.isDirectory()) {
                List<String> classNamesC = doScenner(scanPackage + "." + file.getName());
                classNames.addAll(classNamesC);
            } else {
                if (!file.getName().endsWith(".class")) {
                    continue;
                }
                String className = scanPackage + "." + file.getName().replace(".class", "");
                classNames.add(className);
            }
        }
        return classNames;
    }


    /**
     * 从包package中获取所有的Class
     *
     * @param packageName
     * @return
     */

    public Set getClasses(String packageName) throws Exception {

// 第一个class类的集合

//List> classes = new ArrayList>();

        Set classes = new HashSet<>();

// 是否循环迭代
        boolean recursive = true;

// 获取包的名字 并进行替换

        String packageDirName = packageName.replace('.', '/');

// 定义一个枚举的集合 并进行循环来处理这个目录下的things

        Enumeration dirs;

        try {

            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);

// 循环迭代下去

            while (dirs.hasMoreElements()) {

// 获取下一个元素

                URL url = (URL) dirs.nextElement();

// 得到协议的名称

                String protocol = url.getProtocol();

// 如果是以文件的形式保存在服务器上

                if ("file".equals(protocol)) {

// 获取包的物理路径

                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");

// 以文件的方式扫描整个包下的文件 并添加到集合中

                    addClass(classes, filePath, packageName);

                } else if ("jar".equals(protocol)) {

// 如果是jar包文件

// 定义一个JarFile

                    JarFile jar;

                    try {

// 获取jar

                        jar = ((JarURLConnection) url.openConnection()).getJarFile();

// 从此jar包 得到一个枚举类

                        Enumeration entries = jar.entries();

// 同样的进行循环迭代

                        while (entries.hasMoreElements()) {

// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件

                            JarEntry entry = (JarEntry) entries.nextElement();

                            String name = entry.getName();

// 如果是以/开头的

                            if (name.charAt(0) == '/') {

// 获取后面的字符串

                                name = name.substring(1);

                            }

// 如果前半部分和定义的包名相同

                            if (name.startsWith(packageDirName)) {

                                int idx = name.lastIndexOf('/');

// 如果以"/"结尾 是一个包

                                if (idx != -1) {

// 获取包名 把"/"替换成"."

                                    packageName = name.substring(0, idx).replace('/', '.');

                                }

// 如果可以迭代下去 并且是一个包

                                if ((idx != -1) || recursive) {

// 如果是一个.class文件 而且不是目录

                                    if (name.endsWith(".class") && !entry.isDirectory()) {

// 去掉后面的".class" 获取真正的类名

                                        String className = name.substring(packageName.length() + 1, name.length() - 6);

                                        try {

// 添加到classes

                                            classes.add(Class.forName(packageName + '.' + className));

                                        } catch (ClassNotFoundException e) {

                                            e.printStackTrace();

                                        }

                                    }

                                }

                            }

                        }

                    } catch (IOException e) {

                        e.printStackTrace();

                    }

                }

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

        return classes;

    }

    public void addClass(Set classes, String filePath, String packageName) throws Exception {

        File[] files = new File(filePath).listFiles(file -> (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory());

        assert files != null;

        for (File file : files) {

            String fileName = file.getName();

            if (file.isFile()) {

                String classsName = fileName.substring(0, fileName.lastIndexOf("."));

                if (!packageName.isEmpty()) {

                    classsName = packageName + "." + classsName;

                }

                doAddClass(classes, classsName);

            }

        }

    }

    //
    public void doAddClass(Set classes, final String classsName) throws Exception {

        ClassLoader classLoader = new ClassLoader() {

            @Override

            public Class loadClass(String name) throws ClassNotFoundException {

                return super.loadClass(name);

            }

        };

        classes.add(classLoader.loadClass(classsName));

    }

    public List<Class> getAnnotationClasses(String packageName, Class annotationClass) throws Exception {

//找用了annotationClass注解的类

        List<Class> controllers = new ArrayList<>();

        Set<Class> clsList = getClasses(packageName);

        if (clsList != null && clsList.size() > 0) {

            for (Class cls : clsList) {

                if (cls.getAnnotation(annotationClass) != null) {

                    controllers.add(cls);

                }

            }

        }

        return controllers;

    }

  

posted @ 2022-10-08 11:51  higsan  阅读(57)  评论(0编辑  收藏  举报