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; } }