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. SQL索引优化,菜单列表优化

    SQL索引优化,菜单列表优化 现象:在系统中几个数据量大的列表页面,首次进入页面未增加筛选条件,导致进入的列表查询速度非常慢.分析:通过SQL查看,是做了count求和查询,然后根据总的记录数来做分页 ...

  2. MySQL入门到实战详细教程

    MySQL介绍 MySQL是一个开源的关系型数据库管理系统(RDBMS),由瑞典 MySQL AB 公司开发,属于 Oracle 旗下产品,它广泛应用于各种Web应用程序和网站,MySQL使用结构化查 ...

  3. 分享两个内置Google广告位的Typecho主题

    前言 很多项目的开始都是因为情怀和热爱,"为爱发电"是一件很值得尊敬的事情,然而大量"为爱发电"的项目最后却不得不因"难以为继"而被迫停服. ...

  4. 新知识get,vue3是如何实现在style中使用响应式变量?

    前言 vue2的时候想必大家有遇到需要在style模块中访问script模块中的响应式变量,为此我们不得不使用css变量去实现.现在vue3已经内置了这个功能啦,可以在style中使用v-bind指令 ...

  5. ASP.NET Core修改CentOS的IP地址

    最近做的一个产品中有个需求,就是客户使用的时候可以通过Web网页修改服务器的IP地址(客户是普通使用者,没有Linux使用经验,我们的产品作为一台服务器部署到客户机房,客户通过HTTP方式访问使用). ...

  6. [oeasy]python0036_牛说_cowsay_小动物说话_asciiart_figlet_lolcat_管道(祝大家新年快乐~)

    ​ 牛说(cowsay) 回忆上次内容 上次我们研究了shell脚本的编程 并且在shell中实现了 循环语句 延迟命令 清屏命令 python命令 figlet命令 ​ 编辑 还能整点什么呢? 还想 ...

  7. oeasy教您玩转vim - 60- # vim选项

    ​ vim选项 从头开始 这次我们从头开始 从进入vim之前开始 我们可以在终端里面给vim怎么样的参数呢? man vim 这个如果不行的话 要先运行unminimize更新manual 也可以在v ...

  8. .NET单元测试使用AutoFixture按需填充属性的几种方式,以及最佳实践

    AutoFixture是一个.NET库,旨在简化单元测试中的数据设置过程.通过自动生成测试数据,它帮助开发者减少测试代码的编写量,使得单元测试更加简洁.易读和易维护.AutoFixture可以用于任何 ...

  9. SUM-ACM天梯赛

    第一次天梯赛: B-B:孵化小鸡 题解:二进制枚举所有可能性,一个一个枚举出来,@离散数学,真值表. 题目如下: 二进制枚举代码如下 点击查看代码 #include <bits/stdc++.h ...

  10. VUE系列之性能优化--懒加载

    一.懒加载的基本概念 懒加载是一种按需加载技术,即在用户需要时才加载相应的资源,而不是在页面初始加载时一次性加载所有资源.这样可以减少页面初始加载的资源量,提高页面加载速度和用户体验. 二.Vue 中 ...