当前位置: 首页 > news >正文

纯原生Java实现:获取整个项目中指定接口所有的实现类

不使用第三方,不使用属性文件,不指定包名,获取整个系统中某一个接口所有的实现类,纯Java实现

/*** 类查找器,用于扫描类路径中的所有类,并找出指定类的实现类。* 该类通过递归扫描类路径下的所有 .class 文件,加载并判断是否为目标类的实现类。*/
public class ClassFinder {/*** 获取指定类的所有实现类(非接口本身)。* 从类路径根目录开始扫描,使用当前线程的类加载器获取资源路径。** @param clazz 要查找实现类的目标类(通常是抽象类或接口)* @return 返回目标类的所有实现类组成的列表*/public static List<Class<?>> getImplementationsOfMyService(Class<?> clazz) {List<Class<?>> implementations = new ArrayList<>();// 设置为空字符串表示从类路径根开始扫描String packageName = "";// 使用当前线程的类加载器加载类资源ClassLoader classLoader = Thread.currentThread().getContextClassLoader();Enumeration<URL> resources = null;try {// 获取类路径下对应包名的资源路径(转换为文件系统路径格式)resources = classLoader.getResources(packageName.replace('.', '/'));while (resources.hasMoreElements()) {URL resource = resources.nextElement();File file = new File(resource.getFile());// 开始递归扫描该目录下的类文件scanDirectory(clazz, file, "", implementations);}} catch (IOException e) {e.printStackTrace();}return implementations;}/*** 递归扫描目录及其子目录中的类文件。* 对每个类文件进行加载并判断是否是目标类的实现类。** @param clazz 目标类(要查找其实现类)* @param dir 当前扫描的目录* @param pkg 当前目录对应的包名前缀* @param list 存储符合条件的实现类*/private static void scanDirectory(Class<?> clazz, File dir, String pkg, List<Class<?>> list) {if (!dir.exists()) return;for (File file : Objects.requireNonNull(dir.listFiles())) {if (file.isDirectory()) {// 如果是目录,递归进入子目录继续扫描scanDirectory(clazz, file, pkg + file.getName() + ".", list);} else if (file.getName().endsWith(".class")) {// 构建完整的类名(包含包名)String className = pkg + file.getName().replace(".class", "");try {// 加载类Class<?> tmp = Class.forName(className);// 判断是否为目标类的实现类,并排除接口类型if (clazz.isAssignableFrom(tmp) && !tmp.isInterface()) {list.add(tmp);}} catch (Exception ignored) {// 忽略加载失败的类}}}}// 测试入口:演示如何使用ClassFinder查找AnnotationHandler接口的实现类public static void main(String[] args) throws Exception {// 查找AnnotationHandler接口的所有实现类List<Class<?>> classes = getImplementationsOfMyService(AnnotationHandler.class);System.out.println("找到以下实现类:");for (Class<?> c : classes) {System.out.println(c.getName());}}
}
http://www.dtcms.com/a/168717.html

相关文章:

  • 柔性超声耦合剂的选择与设计-可穿戴式柔性超声耦合剂面临的难题
  • [面试]SoC验证工程师面试常见问题(三)
  • 冯·诺依曼体系:现代计算机的底层逻辑与百年传承
  • 深度学习框架PyTorch——从入门到精通(YouTube系列 - 4)——使用PyTorch构建模型
  • 实现水平垂直居中的多种方法
  • 多模态RAG演进-MRAG1.0->MRAG2.0->MRAG3.0
  • 【验证技能】VIP项目大总结
  • C++派生类核心机制:类型转换与对象复制控制深度剖析
  • 通信协议记录仪-产品规格书
  • 如何让通义千问大模型支持结构化输出?
  • 使用xlwings将两张顺序错乱的表格进行数据核对
  • NVIDIA Omniverse在数字孪生中的算力消耗模型构建方法
  • C++ std::initializer_list 详解
  • 为美好的XCPC献上典题 ABC359 G - Sum of Tree Distance(根号分治)
  • 【AI面试准备】传统测试工程师Prompt Engineering转型指南
  • 在 Windows 中安装 Pynini 的记录
  • ECMAScript 2(ES2):标准化的微调与巩固
  • 每天一道算法题——推多米诺
  • leetcode 838. 推多米诺 中等
  • A2A Python 教程 - 综合指南
  • 深度理解linux系统—— 进程切换和调度
  • 数据结构-线性结构(链表、栈、队列)实现
  • Python 中 DAO 层使用泛型的探索
  • 接口测试实战指南:从入门到精通的质量保障之道
  • Linux系统:详解文件描述符与重定向原理以及相关接口(open,read,write,dup2)
  • 分布式理论:常见分布式协议的概览与解析
  • 51c大模型~合集123
  • C++ 复习
  • AI驱动文字冒险游戏
  • 第 12 届蓝桥杯 C++ 青少组中 / 高级组省赛 2021 年真题