java獲取包下所有的類

1.背景

給一個Java的包名,獲取包名下的所有類..

根據類上的註解,可以展開很多統一操作的業務

2.直接看代碼

package com.common.config.mq.supplier;

import com.common.config.mq.MqRegister;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;

/**
 * @Copyright (C) XXXXX技有限公司
 * @Author: ldp
 * @Date: 2023/4/19 10:41
 * @Description:
 */
@Slf4j
public class MqSupplierConstHelp {

    /**
     * 獲取當前包路徑下的隊列
     *
     * @return
     * @throws Exception
     */
    public Set<String> getSupplierQueueList() throws Exception {
        String basePackageName = this.getClass().getPackage().getName();
        log.info("basePackageName=" + basePackageName);
        // 獲取包的磁盤路徑
        String dirPath = getDirPath(basePackageName);
        // 獲取磁盤路徑下的Java對象
        List<String> classNameList = getClassNameList(dirPath);
        log.info("classNameList" + classNameList);
        // 獲取到class字節碼集合
        List<Class<?>> classList = getClassList(classNameList, basePackageName);
        // 獲取到帶有註解的字段值
        Set<String> fieldQueueNameList = getFieldQueueName(classList);
        return fieldQueueNameList;
    }

    /**
     * 根據包名獲取磁盤路徑
     *
     * @param basePackageName
     * @return
     * @throws Exception
     */
    private String getDirPath(String basePackageName) throws Exception {
        String path = basePackageName.replace(".", "\\");
        ClassLoader loader = ClassLoader.getSystemClassLoader();
        //獲取編譯後的class文件夾路徑dirPath
        Enumeration<URL> enums = loader.getResources(path);
        String dirPath = "";
        while (enums.hasMoreElements()) {
            URL url = enums.nextElement();
            if (url != null) {
                String protool = url.getProtocol();
                if ("file".equals(protool)) {
                    dirPath = url.getPath();
                    dirPath = URLDecoder.decode(dirPath, "utf-8");
                    log.info("dirPath=" + dirPath);
                }
            }
        }
        return dirPath;
    }

    /**
     * 獲取磁盤路徑下的Java對象
     *
     * @param dirPath
     * @return
     */
    private List<String> getClassNameList(String dirPath) {
        List<String> classNameList = new ArrayList<>();
        //根據傳入文件夾路徑創建File對象
        File dir = new File(dirPath);
        //檢查是否爲文件夾
        if (dir.isDirectory()) {
            //遍歷文件夾內的文件
            for (File f : dir.listFiles()) {
                //獲取文件名,並刪除後綴 xxx.class
                String fileName = f.getName();
                String[] split = fileName.split("\\.");
                if (split.length != 2) {
                    continue;
                }
                if (!split[1].equals("class")) {
                    continue;
                }
                fileName = fileName.substring(0, fileName.lastIndexOf("."));
                //添加到結果中
                classNameList.add(fileName);
            }
        }
        return classNameList;
    }

    /**
     * 拼接class全路徑
     *
     * @param classNames
     * @param basePackageName
     * @return
     */
    private List<Class<?>> getClassList(List<String> classNames, String basePackageName) {
        //將獲取到的包內文件名轉換爲反射對象
        List<Class<?>> classes = new ArrayList<>();
        for (String className : classNames) {
            try {
                classes.add(Class.forName(basePackageName + "." + className));
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        return classes;
    }

    /**
     * 根據字節碼,獲取帶有註解的常量對象的字段值
     *
     * @param classList
     * @return
     * @throws Exception
     */
    private Set<String> getFieldQueueName(List<Class<?>> classList) throws Exception {
        Set<String> set = new HashSet();
        for (Class<?> aClass : classList) {
            MqRegister mqRegister = aClass.getAnnotation(MqRegister.class);
            if (mqRegister == null) {
                continue;
            }
            log.info("可以註冊的常量對象:{}", aClass.getName());
            Object mqConst = aClass.newInstance();
            // 可以註冊
            Field[] fields = aClass.getFields();
            for (Field field : fields) {
                String fieldName = field.getName();
                String queueName = field.get(mqConst).toString();
                log.info("可以註冊的字段名稱:" + fieldName + ",字段值:" + queueName);
                set.add(queueName);
            }
        }
        return set;
    }
}

 

完美!

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