java获取包下所有的类
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获取包下所有的类的更多相关文章
- 【第二周】关于java.util包下的Random类
1.功能:此类的实例用于生成伪随机数流 2.方法(Random的方法有很多,在此只解释说明我认为比较常用的几个方法) (1)next(int bits):生成下一个伪随机数 (2)nextDouble ...
- java.io 包下的类有哪些 + 面试题
java.io 包下的类有哪些 + 面试题 IO 介绍 IO 是 Input/Output 的缩写,它是基于流模型实现的,比如操作文件时使用输入流和输出流来写入和读取文件等. IO 分类 传统的 IO ...
- java工具类 获取包下所有类
extends:http://blog.csdn.net/jdzms23/article/details/17550119 package com.threeti.util; import java. ...
- Java 获取指定包下的所有类
package com.s.rest.util; import java.io.File; import java.io.FileFilter; import java.io.IOException; ...
- Java反射1——扫描某个包下的所有类
1.从包package中获取所有的Class /** * 从包package中获取所有的Class * * @param pack * @return */ public static Set< ...
- Java 扫描包下所有类(包括jar包)
package com.MyUtils.file; [java] view plain copy import java.io.File; import java.io.FileFilter; imp ...
- java.util.regex包下的Pattern类和Matcher类的使用总结
一.介绍 Java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现1.Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不 ...
- List,Set,Map在java.util包下都是接口 List有两个实现类:ArrayList和LinkedList Set有两个实现类:HashSet和LinkedHashSet AbstractSet实现了Set
List,Set,Map在java.util包下都是接口 List有两个实现类:ArrayList和LinkedListSet有两个实现类:HashSet和LinkedHashSetAbstractS ...
- java 获取classpath下文件多种方式
java 获取classpath下文件多种方式 一:properties下配置 在resources下定义server.properties register.jks.path=classpath\: ...
- spring java 获取webapp下文件路径
spring java 获取webapp下文件路径 @RequestMapping("/act/worldcup_schedule_time/imgdownload") @Resp ...
随机推荐
- MyBatis 的好处是什么?
a.MyBatis 把 sql 语句从 Java 源程序中独立出来,放在单独的 XML 文件中编写,给程序的维护带来了很大便利. b.MyBatis 封装了底层 JDBC API 的调用细节,并能自动 ...
- Centos7部署FytSoa项目至Docker——第二步:安装Mysql、Redis
FytSoa项目地址:https://gitee.com/feiyit/FytSoaCms 部署完成地址:http://82.156.127.60:8001/ 先到腾讯云申请一年的云服务器,我买的是一 ...
- IT运维全面数字化|芯片设计行业领跑打造运维流程闭环
在当今数字化转型的浪潮中,科技行业正经历着前所未有的变革.随着5G.人工智能.物联网等新兴技术的快速发展,企业对于高效.智能的运营模式的需求日益迫切. 芯片设计公司作为科技产业链中的关键一环,不仅要在 ...
- pytest-allure 命令生成的报告,test body 没有具体的参数和日志
run.py: pytest.main([命令参数执行]),pytest命令执行完毕后,使用os.system()执行allure的命令 原因: 使用了命令:os.system('allure gen ...
- P1551 亲戚 题解。。。
并查集 目录 并查集 (1.概念: (2.详解 Q1:如何表示不同的家族 ans1: Q2:如何将两个人归到同一个家族中 ans2: CODE: PS: (1.概念: 处理 不相交 可合并 的集合关系 ...
- 移动web开发入门
一,视口 <meta name="viewport" content="width=device-width, initial-scale=1, user-scal ...
- Kubernetes(五) Pod控制器详解
Pod控制器详解 本章主要介绍Pod控制器的详细使用 1. Pod控制器介绍 在kubernetes中,按照pod的创建方式可以将其分为2类: 自主式pod:kubernetes直接创建出来的pod, ...
- .NET 中使用RabbitMQ初体验
在.NET Core中使用RabbitMQ 前言 逛园子的时候看到一篇.NET 学习RabbitMq的文章(视频地址和文章地址放在文章底部了),写的不错,我也来实现一下. 我是把RabbitMQ放在服 ...
- OpenFOAM v2306 安装
参考 https://develop.openfoam.com/Development/openfoam/-/wikis/precompiled/debian curl https://dl.open ...
- 全志T113-i+玄铁HiFi4开发板硬件说明书(2)
前 言 本文档主要介绍开发板硬件接口资源以及设计注意事项等内容,测试板卡为全志T113-i+玄铁HiFi4开发板,由于篇幅问题,本篇文章共分为上下两集,点击账户可查看更多内容详情,开发问题欢迎留言,感 ...