掃描包并加載Class類

Java掃描包并加載Class類

  • 用途:
  1. 類似SpringBean的掃描某個(gè)包下的類并加載;
  2. 指定某個(gè)包下類的實(shí)例化并進(jìn)行管理,用于快速main方法測(cè)試;
  • 代碼(只描述原理根據(jù)情況自行修改):
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;
import java.util.function.Predicate;

/**
 * 簡(jiǎn)易類掃描加載(只描述原理自行理解)
 * 注:這里只簡(jiǎn)單加載了一層文件的,有多需求可以改寫文件處理
 *
 * @author caoch
 */
public class ClassScanLoad {

    /**
     * 掃描過(guò)濾后實(shí)例化類
     *
     * <pre>
     * 示例:
     * String scanPackage = "com.ttk.agg.cy.base.task.process";
     * instanceClassByScanFilter(scanPackage, StringTextEtlProcess.class, null);
     * </pre>
     *
     * @param scanPackage 掃描包
     * @param resultCls   結(jié)果類型,同時(shí)也是過(guò)濾類型,這些類型必須繼承自某一接口或抽象類
     * @param filter      過(guò)濾器
     * @param <R>         實(shí)例化類型
     * @return 實(shí)例化類
     */
    public static <R> Set<R> instanceClassByScanFilter(String scanPackage, Class<R> resultCls, Predicate<Class<?>> filter) {
        return filterAndInstanceClass(resultCls, getUrlOfScanPackage(scanPackage), filter);
    }

    public static <R> Set<R> filterAndInstanceClass(
            Class<R> resultCls, Set<String> clsNameSet, Predicate<Class<?>> filter) {
        try {
            Set<R> rs = new HashSet<>();
            for (String clsName : clsNameSet) {
                Class<?> aClass = Class.forName(clsName);
                if (resultCls.isAssignableFrom(aClass)) {
                    if (filter == null || filter.test(aClass)) {
                        Object cast = aClass.cast(aClass.newInstance());
                        rs.add(resultCls.cast(cast));
                    }
                }
            }
            return rs;
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public static Set<String> getUrlOfScanPackage(String scanPackage) {
        String scanPackageUrl = scanPackage.replace(".", "/");
        Set<String> clsNameSet = new HashSet<>();
        try {
            Enumeration<URL> resources = ClassScanLoad.class
                    .getClassLoader().getResources(scanPackageUrl);
            while (resources.hasMoreElements()) {
                URL url = resources.nextElement();
                if ("file".equals(url.getProtocol())) {
                    File file = new File(url.toURI());
                    // System.out.println(file.getPath());
                    if (file.exists() && file.isDirectory()) {
                        File[] files = file.listFiles();
                        if (files != null) {
                            for (File clsFile : files) {
                                if (clsFile.exists() && !clsFile.isDirectory()) {
                                    // System.out.println(clsFile.getName());
                                    String clsFileName = clsFile.getName();
                                    if (clsFileName.endsWith(".class")) {
                                        String clsUrlName = scanPackage + "." + clsFileName.replace(".class", "");
                                        clsNameSet.add(clsUrlName);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return clsNameSet;
        } catch (IOException | URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 遞歸文件夾
     */
    private static List<File> fileDepth(File file, Predicate<File> fileFilter) {
        List<File> list = null;
        if (file.exists()) {
            if (fileFilter == null || fileFilter.test(file)) {
                // 是否目錄
                if (file.isDirectory()) {
                    File[] files = file.listFiles();
                    if (files != null) {
                        list = new ArrayList<>(files.length);
                        for (File clsFile : files) {
                            List<File> depthFiles = fileDepth(clsFile, fileFilter);
                            if (!depthFiles.isEmpty()) {
                                list.addAll(depthFiles);
                            }
                        }
                    }
                } else {
                    list = new ArrayList<>(1);
                    list.add(file);
                }
            }
        }
        if (list == null) {
            list = new ArrayList<>(0);
        }
        return list;
    }

}


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容