掃描指定package包下的類的工具類

    最近在做自己的springMVC的輪子,涉及指定包下類的加載,所以寫了一下此工具類。

package com.jsalpha.utils.load;

import com.jsalpha.utils.common.DirectoryFileFilter;
import com.jsalpha.utils.common.SuffixFilenameFilter;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

/**
 * @author dengjingsi
 * 加載指定包下的類的工具類
 */
public class ClassOfPackageLoader {

    /**
     * 加載path目錄下的packageName中所有類
     * @param path package所在的地址
     * @param packageName package的名字
     * @throws ClassNotFoundException
     */
    public void loadInnerClassOfpackage(String path,String packageName) throws ClassNotFoundException {
        //存儲掃描到的類名變量
        LinkedList<String> classNames = new LinkedList<>();
        //獲取包下的所有的類名
        collectClassOfPackageInner(path,packageName,classNames);
        //加載所有掃描到的類
        loadClass(classNames);
    }

    /**
     * 根據提供的包名,以及包所在的地址,掃描並存儲package下的所有類的類名
     * @param path package的地址
     * @param packageName 包名
     * @param classes 供存儲類名的變量
     * @throws ClassNotFoundException
     */
    public void collectClassOfPackageInner(String path,String packageName,LinkedList<String> classes){
        String packagePath = packageName.replace(".",File.separator);
        File f = new File(path+File.separator+packagePath);
        String[] fileNames = null;
        if(f.exists()){
            //獲取該路徑下所有的.class類文件
            fileNames = f.list(new SuffixFilenameFilter());
            for(String classFileName : fileNames){
                classFileName = classFileName.substring(0,classFileName.length()-6);
                classes.add(packageName+"."+classFileName);
            }
            //獲取該路徑下的所有目錄
            File[] files = f.listFiles(new DirectoryFileFilter());
            for(File file : files){
                collectClassOfPackageInner(path,packageName+"."+file.getName(),classes);
            }
        }
    }

    /**
     * 根據classNames中類名,加載所有類
     * @param classNames 需要加載的類名集合
     * @throws ClassNotFoundException
     */
    public void loadClass(List<String> classNames) throws ClassNotFoundException {
        for(String className : classNames){
            loadClass(className);
        }
    }

    /**
     * 加載類名爲className的類
     * @param className 需要加載的類名
     * @return
     * @throws ClassNotFoundException
     */
    public Class<?> loadClass(String className) throws ClassNotFoundException {
        return this.getClass().getClassLoader().loadClass(className);
    }


    public static void main(String[] args) throws ClassNotFoundException{
        /**
         * 測試
         * 注意:如果你的測試結果報ClassNotFoundException異常,請檢查你的classPath參數對應的路徑下有沒有指定的包
         */
        ClassOfPackageLoader myClassLoader = new ClassOfPackageLoader();
        //下邊是我測試的包所在絕對地址和包名
        myClassLoader.loadInnerClassOfpackage("/Users/iyunxiao/IdeaProjects/utils/target/classes","com.jsalpha.utils");
    }
}
package com.jsalpha.utils.common;

import java.io.File;
import java.io.FileFilter;

/**
 * @author dengjingsi
 * 目錄文件過濾器,過濾指定路徑下的目錄
 */
public class DirectoryFileFilter implements FileFilter {
    @Override
    public boolean accept(File pathname) {
        if(pathname.isDirectory()){
            return true;
        }
        return false;
    }
}
package com.jsalpha.utils.common;

import java.io.File;
import java.io.FilenameFilter;

/**
 * @author dengjingsi
 * 實現過濾以某字符串結尾的過濾器,空構造器,默認實現過濾以.class結尾的文件
 */
public class SuffixFilenameFilter implements FilenameFilter {
    private String endWith = ".class";

    /**
     * 構建默認掃描.class後綴的文件過濾器
     */
    public SuffixFilenameFilter() {
    }

    /**
     * 構建掃描endWith後綴的文件過濾器
     * @param endWith
     */
    public SuffixFilenameFilter(String endWith) {
        this.endWith = endWith;
    }

    @Override
    public boolean accept(File dir, String name) {
        if(name.endsWith(endWith)){
            return true;
        }
        return false;
    }
}

項目結構

提醒大家注意:類加載,只是把類的二級制文件加載到JVM而已,並沒有初始化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章