手动加载一个package的class文件

哈哈 题目真不知道怎么写,随便记一下。看到一段代码,作用就是输入一个包名,将包下的所有class加载到一个集合当中。

    public static final String FILE_PROTOCOL = "file";

 

    /**
     * 获取包下的所有的类的集合
     * @param packageName
     */
    public static Set<Class<?>> extractPackageClass(String packageName){
        Set<Class<?>> classSet = null;
        //获取类的加载器,主要为了解决实际路径的问题,包名没办法定位
        ClassLoader classLoader = getClassLoader();
        //通过类加载器加载资源
        URL url = classLoader.getResource(packageName.replace('.', '/'));
        if(url==null){
            System.out.println("资源不存在");
            return classSet;
        }

        //根据不同的资源类型,通过不同的方式获取资源
        //如果是文件协议
        if(url.getProtocol().equalsIgnoreCase(FILE_PROTOCOL)){
            classSet = new HashSet<Class<?>>();
            File packageDir = new File(url.getPath());
            extractClassFile(classSet,packageDir,packageName);
        }

        return classSet;
    }

 

    //提取类文件(需要进行递归,判断是不是文件夹还是文件)
    private static void extractClassFile(final Set<Class<?>> classSet, File fileSoucre, final String packageName) {
        //如果是文件的情况
        if(!fileSoucre.isDirectory()){
            return;
        }
        else {
            //文件夹的情况,列出文件夹下的所有文件
            File[] files = fileSoucre.listFiles(new FileFilter() {
                public boolean accept(File file) {
                     if(file.isDirectory()){
                         return true;
                     }
                     else {
                         //获取文件的绝对路径
                         String absolutePath = file.getAbsolutePath();
                         if(absolutePath.endsWith(".class")){
                                //class文件直接加载
                                add2ClassSet(absolutePath);
                                return true;
                         }

                     }
                     return false;
                }

                /**
                 * 添加class到classSet当中
                 * @param absolutePath
                 */
                private void add2ClassSet(String absolutePath) {
                    System.out.println(absolutePath);
                    //从绝对路径中获取到包名+类名
                    absolutePath = absolutePath.replace(File.separator,".");
                    //根据传进来的packagename,去掉路径中的包名,只得到
                    String className = absolutePath.substring(absolutePath.indexOf(packageName));
                    className = className.substring(0,className.lastIndexOf('.'));
                    Class<?> aClass = loadClass(className);
                    classSet.add(aClass);
                }

                private Class<?> loadClass(String className) {
                    try{
                        return Class.forName(className);
                    }
                    catch (Exception ex){
                        System.out.println("load class error");
                        throw new RuntimeException();
                    }
                }

            });

            if(files!=null){
                //遍历每一个文件
                for (File f : files){
                    extractClassFile(classSet,f,packageName);
                }
            }
        }
    }

  

    /**
     * 获取ClassLoader
     * @return
     */
    public static ClassLoader getClassLoader(){
        //通过这个方式获取ClassLoader实例
        return Thread.currentThread().getContextClassLoader();
    }

  

posted @ 2020-11-20 17:44  奋斗的大橙子  阅读(299)  评论(0)    收藏  举报