1.背景

给一个Java的包名,获取包名下的所有类..

根据类上的注解,可以展开很多统一操作的业务

2.直接看代码-spring环境下

package com.qxnw.digit.scm.common.config.mq.supplier;

import com.qxnw.digit.scm.common.config.mq.MqRegister;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils; import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set; /**
* @Copyright (C) XXXXX技有限公司
* @Author: ldp
* @Date: 2023/4/19 10:41
* @Description:
*/
@Slf4j
public class MqSupplierConstHelp {
private final static String RESOURCE_PATTERN = "/**/*.class"; /**
* 获取当前包路径下的供应商队列
*
* @return
* @throws Exception
*/
public Set<String> getSupplierQueueList() throws Exception {
String basePackageName = this.getClass().getPackage().getName();
log.info("basePackageName=" + basePackageName);
// 获取到class字节码集合
List<Class<?>> classList = getClassList(basePackageName);
// 获取到带有注解的字段值
Set<String> fieldQueueNameList = getFieldQueueName(classList);
return fieldQueueNameList;
} /**
* 通过包名获取项目包下所有类
*
* @param BASE_PACKAGE 包名
* @return
*/
public static List<Class<?>> getClassList(String BASE_PACKAGE) {
List<Class<?>> classes = new ArrayList<>();
//spring工具类,可以获取指定路径下的全部类
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
try {
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
ClassUtils.convertClassNameToResourcePath(BASE_PACKAGE) + RESOURCE_PATTERN;
Resource[] resources = resourcePatternResolver.getResources(pattern);
//MetadataReader 的工厂类
MetadataReaderFactory readerfactory = new CachingMetadataReaderFactory(resourcePatternResolver);
for (Resource resource : resources) {
//用于读取类信息
MetadataReader reader = readerfactory.getMetadataReader(resource);
//扫描到的class
String classname = reader.getClassMetadata().getClassName();
log.info("classname={}", classname);
Class<?> clazz = Class.forName(classname);
classes.add(clazz);
}
} catch (Exception e) {
log.error("获取class异常:", e);
}
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;
}
}

3.直接看代码-非sping环境

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

完美!

java获取包下所有的类的更多相关文章

  1. 【第二周】关于java.util包下的Random类

    1.功能:此类的实例用于生成伪随机数流 2.方法(Random的方法有很多,在此只解释说明我认为比较常用的几个方法) (1)next(int bits):生成下一个伪随机数 (2)nextDouble ...

  2. java.io 包下的类有哪些 + 面试题

    java.io 包下的类有哪些 + 面试题 IO 介绍 IO 是 Input/Output 的缩写,它是基于流模型实现的,比如操作文件时使用输入流和输出流来写入和读取文件等. IO 分类 传统的 IO ...

  3. java工具类 获取包下所有类

    extends:http://blog.csdn.net/jdzms23/article/details/17550119 package com.threeti.util; import java. ...

  4. Java 获取指定包下的所有类

    package com.s.rest.util; import java.io.File; import java.io.FileFilter; import java.io.IOException; ...

  5. Java反射1——扫描某个包下的所有类

    1.从包package中获取所有的Class /** * 从包package中获取所有的Class * * @param pack * @return */ public static Set< ...

  6. Java 扫描包下所有类(包括jar包)

    package com.MyUtils.file; [java] view plain copy import java.io.File; import java.io.FileFilter; imp ...

  7. java.util.regex包下的Pattern类和Matcher类的使用总结

    一.介绍 Java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现1.Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不 ...

  8. List,Set,Map在java.util包下都是接口 List有两个实现类:ArrayList和LinkedList Set有两个实现类:HashSet和LinkedHashSet AbstractSet实现了Set

    List,Set,Map在java.util包下都是接口 List有两个实现类:ArrayList和LinkedListSet有两个实现类:HashSet和LinkedHashSetAbstractS ...

  9. java 获取classpath下文件多种方式

    java 获取classpath下文件多种方式 一:properties下配置 在resources下定义server.properties register.jks.path=classpath\: ...

  10. spring java 获取webapp下文件路径

    spring java 获取webapp下文件路径 @RequestMapping("/act/worldcup_schedule_time/imgdownload") @Resp ...

随机推荐

  1. 从零开始写 Docker(十八)---容器网络实现(下):为容器插上”网线“

    本文为从零开始写 Docker 系列第十八篇,利用 linux 下的 Veth.Bridge.iptables 等等相关技术,构建容器网络模型,为容器插上"网线". 完整代码见:h ...

  2. Interceptor拦截器demo

    Interceptor拦截器demo ##接口测试类 @RestController public class TestController { @RequestMapping(value = &qu ...

  3. 开箱即用的Live2d

    安装 npm i @tomiaa/live2d 代码 <template> <div ref="live2dContentRef" id="live2d ...

  4. Lru-k在Rust中的实现及源码解析

    LRU-K 是一种缓存淘汰算法,旨在改进传统的LRU(Least Recently Used,最近最少使用)算法的性能.将其中高频的数据达到K次访问移入到另一个队列进行保护. 算法思想 LRU-K中的 ...

  5. Coap 协议学习:1-有关概念

    COAP协议简介 不像人接入互联网的简单方便,由于物联网设备大多都是资源限制型的,有限的CPU.RAM.Flash.网络宽带等.对于这类设备来说,想要直接使用现有网络的TCP和HTTP来实现设备实现信 ...

  6. Linux系统获取开发板的文件系统并打包成img文件

    应用情形: 在实际的开发中,由于原系统包含的功能有限,而根据项目的需要,安装了相应的库及运行项目程序所创建的各种文件,和所做 的各种配置,想将调试好的系统打包发布,进行批量生产,就可参考本文提供的方法 ...

  7. centos如何统计磁盘使用总量,以及cpu使用率

    剩余硬盘容量 T: df | awk '{print $4}' |sed 's/Available//g' |sed '/^\s*$/d' | awk '{sum+=$1} END {print su ...

  8. 在OwinSelfHost项目中获取客户端IP地址

    在OwinSelfHost项目中,获取客户端的IP地址可以通过以下方法获得: base.Request.GetOwinContext().Request.RemoteIpAddress 创建一个Owi ...

  9. 洛谷P2658

    我在洛谷第一次发个题解,管理员居然把这题的题解通道关了.... 看到好像没有优先队列的题解,来水一手 思路 形似A* 却不是A* 只需要求出其中一个点到其他点的D系数,所有D系数的最大值即是答案. 数 ...

  10. 解决方案 | 获取所有的打印输出的图纸尺寸的名称GetCanonicalMediaNames返回为空的原因竟然是官方帮助文件给我带来了误导-CAD VBA

    巨大的坑,该代码来自于acadauto_2014--AutoCAD2014 ActiveX Reference Guide.chm 但是存在一个巨大的bug. '获取所有的打印输出的图纸尺寸的名称 , ...