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 ...
随机推荐
- session 和 cookie 有什么区别?
a.存储位置不同:session 存储在服务器端:cookie 存储在浏览器端. b.安全性不同:cookie 安全性一般,在浏览器存储,可以被伪造和修改. c.容量和个数限制:cookie 有容量限 ...
- vite+vue3+ts+elementPlus前端框架搭建 [二] pinia状态管理
前面已经完成了基本框架搭建,下一步针对各个模块的封装以及实验 本章主要是针对pinia的状态模块实现 1. 创建Store 在src文件夹下创建一个store的文件夹,并在该文件夹下创建index.t ...
- 彻底解决IDEA Jrebel 错误找不到口令文件的问题
本来我的Jrebel也是好用的,突然就变成了这个样子,网上针对这个问题有很多帖子,但是每次新建项目后我都需要去解决一下这个问题,这我不能忍,经过一整天的百度和测试终于找到了原因并解决这个问题,伸手党直 ...
- python正则表达式替换所有内容并同时保留找到的内容
除了一些专业的工具,例如ue,大部分编程语言的函数包都挺让人迷惑的,例如Java,js. 因为的确有许多功能是很常用的,但是他们又不提供,非得要程序员自己去实现,或者是利用三方的包. 到底是什么理由了 ...
- 01-Python介绍、安装与入门
Python介绍 关于Python Python 是一种解释型.面向对象.动态数据类型的高级程序设计语言. 解释型:Python将代码边解释边运行,而不是像C一样编译.类似解释型的语言还有JAVA. ...
- 实验11.ACL实验
# 实验11.ACL实验 本实验用于测试ACL,类似于防火墙. 拓扑 要求阻塞PC1到PC2和server的全部协议,阻塞client1到server1的icmp协议 具体配置 首先利用ospf协议实 ...
- ClickHouse介绍(三)MergeTree系列表引擎
MergeTree系列表引擎 ClickHouse中最核心的引擎当属MergeTree系列引擎,其中基础表引擎为MergeTree,常用的表引擎还有ReplacingMergeTree.Summing ...
- Android 耳机驱动知识
Android 耳机驱动知识 2015-03-06 工作以后接手的第一个驱动就是android平台下耳机的插拔检测和按键检测.这部分涉及的硬件知识比较简单,但是软件上对中断的处理,软件检测的鲁棒性,都 ...
- Linux设备模型:4、sysfs
作者:wowo 发布于:2014-3-14 18:31 分类:统一设备模型 http://www.wowotech.net/device_model/dm_sysfs.html 前言 sysfs是一个 ...
- 域套接字sendto errno -11分析
sendto errno -11代码分析 errno -11在内核代码中代表EAGAIN(再试⼀次),域套接字sendto过程中 sendto->sock_sendmsg->unix_dg ...