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