获取包名下的所有接口

1 通过包名获取下面所有的类名集合

2 通过类名集合反射获得类对象

-->可以选择拿到标记自定义注解的接口 

.filter(clazz -> clazz.getAnnotation(TrpcApi.class) != null)

-->也可以不标记拿到全部接口

3 通过类对象拿到所有的接口

 /*** 实现包扫描,通过包名拿到其下面所有的接口* @param packageName 包名*/public RpcBootStart scan(String packageName) {//1根据包名拿到所有类名List<String>classnames=getClassName(packageName);//2反射过滤后的接口集合//.filter(clazz -> clazz.getAnnotation(TrpcApi.class) != null)//用于只获取自己标记的接口,删除可变为标记全部List<Class<?>> classes = classnames.stream().map(classname -> {try {//通过名字反射得到class对象return Class.forName(classname);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}//过滤所有不含注解的类}).filter(clazz -> clazz.getAnnotation(TrpcApi.class) != null).collect(Collectors.toList());for (Class<?> clazz : classes) {//获取接口集合Class<?>[] interfaces = clazz.getInterfaces();Object instance=null;try {instance= clazz.getConstructor().newInstance();} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {e.printStackTrace();}                  }

1 进行数据清洗,得到一个合适的路径,去除中文乱码,得到一个包的基本路径

2 返回一个类名集合

 /**** @param packageName 包名* @return 其下面---类名集合*/private List<String> getClassName(String packageName) {//1 获取绝对路径 转义拿到String basePath=packageName.replaceAll("\\.","/");URL url = ClassLoader.getSystemClassLoader().getResource(basePath);if (url == null){throw new RuntimeException("包扫描路径发生异常");}//转义包名String absolutePath = url.getPath();try {absolutePath = URLDecoder.decode(absolutePath, "utf-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}ArrayList<String> classNames = new ArrayList<>();recursionFile(absolutePath,classNames,basePath);return classNames;}

 1 通过拿到基本路径去递归得到文件

/*** 递归获取包名下所有类名* @param absolutePath 转义包名* @param classNames 所有类名*/private ArrayList<String> recursionFile( String absolutePath,ArrayList<String> classNames,String basePath) {File file = new File(absolutePath);//判断是否是文件夹if (file.isDirectory()){File []childedFile=file.listFiles(new FileFilter() {@Overridepublic boolean accept(File pathname) {return pathname.isDirectory() || pathname.getPath().contains(".class");}});if (childedFile.length==0 || childedFile==null) return classNames;for (File child : childedFile) {if (child.isDirectory()){//如果是文件价夹递归调用recursionFile(child.getAbsolutePath(),classNames,basePath);}else {//不是文件夹放在集合中String className= getClassNameByAbsolutePath(child.getAbsolutePath(), basePath);classNames.add(className);}}}else {//不是文件夹放在集合中String className= getClassNameByAbsolutePath(absolutePath, basePath);classNames.add(className);}return classNames;}

 再次进行数据清洗,得到所有.class开头的类的绝对路径加入集合返回

/**** @param absolutePath 当前包名* @param basePath 绝对包名路径* @return 类名的绝对路径*/private String getClassNameByAbsolutePath(String absolutePath,String basePath) {//D:\0_项目管理\TRpc\TRpc_Framework\TRpc_Framework_Core\target\classes\com\trpc\channelHandler\ConsumerChannelInitializer.class//转成com\trpc\channelHandlerString fileName = absolutePath.substring(absolutePath.indexOf(basePath.replaceAll("/","\\\\")));//转成com.trpc.channelHandlerfileName=fileName.replaceAll("\\\\", ".");fileName=fileName.substring(0,fileName.indexOf(".class"));return fileName;}

 

标记注解:用于添加在接口上,添加是可以在包扫描是获取到该接口

package com.trpc.annotation;import com.sun.istack.internal.Interned;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 自定义注解*/
@Target(ElementType.TYPE) //在类上面使用
@Retention(RetentionPolicy.RUNTIME) //允行时生效
public @interface TrpcApi {
}

 接口

package com.trpc.api;import com.trpc.annotation.TryTimes;public interface HaloApi {String halo(String name);
}

需要添加在具体实现上 

package com.trpc.service.Imp;import com.trpc.annotation.TrpcApi;
import com.trpc.api.HaloApi;@TrpcApi
public class HaloServiceImp implements HaloApi {@Overridepublic String halo(String name) {return "halo"+name;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/77012.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【STL】模拟实现map和set {带头结点的红黑树;红黑树的核心结构;红黑树的迭代器;红黑树的插入和查找;map和set的封装}

模拟实现map和set map和set是红黑树的两种不同封装形式&#xff0c;底层使用同一颗泛型结构的红黑树。set是红黑树的K模型&#xff1b;map是红黑树的KV模型。 下面的代码和讲解着重体现红黑树的底层实现和map\set上层封装的衔接。关于二叉搜索树性质&#xff0c;map和set的介…

UMA 2 - Unity Multipurpose Avatar☀️四.UMA人物部位的默认颜色和自定义(共享)颜色

文章目录 🟥 人物颜色介绍1️⃣ 使用默认颜色2️⃣ 使用自定义颜色🟧 UMA自定义颜色的作用🟨 自定义颜色还可作为共享颜色🟥 人物颜色介绍 UMA不同部位的颜色分为默认的内置颜色和我们新定义的颜色. 1️⃣ 使用默认颜色 比如不勾选UseSharedColor时,使用的眼睛的默认…

【搭建本地yum仓库源】

一、环境准备 1.准备两台虚拟机&#xff0c;一台为服务端&#xff08;安装yum源&#xff09;&#xff0c;一台为客户端&#xff08;测试yum源安装结果&#xff09; IP地址主机角色备注192.168.200.21服务端上传镜像到此台机器192.168.200.18客户端 2.准备镜像文件&#xff0…

品牌策划经理工作内容|工作职责|品牌策划经理做什么?

一位美国作家曾说过“品牌是一系列期望、记忆、故事和关系&#xff0c;他们共同构成了消费者最终原则一个产品或者服务的原因。” 所以&#xff0c;品牌经理这个岗位主要是创造感知价值主张&#xff0c;激发消费者购买这个品牌后带来的感知价值&#xff0c;这种回报的本质相对…

Git 基本操作【本地仓库与远程仓库的推送、克隆和拉取】

文章目录 一、Git简介二、Git的下载安装三、Git常规命令四、新建本地仓库五、本地分支操作六、Git远程仓库七、远程仓库克隆、抓取和拉取八、总结九、学习交流 一、Git简介 Git是分布式版本控制系统&#xff08;Distributed Version Control System&#xff0c;简称 DVCS&…

使用rpm重新安装包

#查询 rpm -qa | grep cloudstack #卸载 rpm -e cloudstack-agent-4.18.0.0-1.x86_64 #安装 rpm -ivh cloudstack-agent-4.18.0.0-1.x86_64.rpm

linux 文件系统命令

文件系统命令 磁盘空间使用 linux 可以对组进行配额限制 1、vi /etc/fstab 文件 将要设置配额的分区设置开机自动挂载在添加行在 defaults 后面加上&#xff0c;usrquota&#xff08;grpquota&#xff09;表示要建立用户或组的磁盘配额 2、重新挂载文件系统 之前重启看效果&…

uniapp 微信小程序分享功能(打开右上角分享)

1. 新建share.js文件, 目录为: /static/js/share.js export default {data() {return {share: {// 转发的标题 &#xff08;默认标题&#xff09;title: 默认标题,// 默认是当前页面&#xff0c;必须是以‘/’开头的完整路径path: ,//自定义图片路径&#xff0c;可以是本地文件…

说说什么是间隙锁

分析&回答 间隙锁为了解决RR&#xff08;可重复读&#xff09;级别下当前读导致的幻读问题&#xff0c;锁的对象是索引叶子节点的next指针。 快照读 在RR隔离级别下&#xff1a;快照读有可能读到数据的历史版本&#xff0c;也有可能读到数据的当前版本。所以快照读无需用…

【PowerQuery】PowerQuery学习路径

PowerQuery这么好,怎么去学习呢?相信很多初读本书的朋友迫切的希望了解整个PowerQuery全景知识和它提供的相应的功能。但是对于PowerQuery来说,一开始就会进行自定义函数的构建当然也是不可能的,这里有相应的学习路径来进行由浅入深的学习,帮助读者更好的理解PowerQuery的…

leetcode 649. Dota2 参议院

2023.9.11 先简化一下题意&#xff1a;本题的意思就是每次投票中&#xff0c;前面的议员可以干掉后面的议员(当然是干掉敌对方的)&#xff0c;然后他将参与下一次的投票&#xff0c;而被干掉的议员则不能参与投票了。 如&#xff1a;[R D D] -> [R D] ->[R D]->[D] 。…

【算法基础】时间复杂度和空间复杂度

目录 1 算法的评价 2 算法复杂度 2.1 时间复杂度&#xff08;Time Complexity&#xff09; 2.1.1 如何计算时间复杂度&#xff1a; 2.1.2 常见的时间复杂度类别与示例 2.2 空间复杂度 2.2.1 如何计算空间复杂度 2.2.2 常见的空间复杂度与示例 3 时间复杂度和空间复杂度…

【附安装包】2023最新版Python安装详细教程!一键安装,永久使用

一、python官网 Python官网主要有python的About (简介)、Downloads (下载)、Documentation(文档)、Community (团体)、Success Stories (成功案例)、News (新闻)、Events (事件动态)等栏目。 Python官网地址&#xff1a;https://www.python.org/ 【领取方式见文末】 二、在…

免费的低代码助力售后工单管理:快速搭建,高效定制

编者按&#xff1a;本文旨在阐述免费且高效的低代码平台在实现售后工单管理系统方面的优势、功能及其作用。这些优势和功能对于提高企业的服务质量和效率具有重要的意义。 关键词&#xff1a;低代码平台、售后工单系统、私有化部署 1.售后工单系统有什么作用&#xff1f; 售后工…

day55:C++ day5,运算符重载剩余部分、静态成员、继承

#include <iostream> #include <cstring> #define pi 3.14 using namespace std;class Shape { protected:double round;double area; public://无参构造Shape():round(40),area(100){cout<<"Shape::无参构造函数&#xff0c;默认周长为40&#xff0c;面…

Python的命令行参数

Python的命令行参数&#xff0c;提供了很多有用的功能&#xff0c;可以方便调试和运行&#xff0c;通过man python就能查看&#xff0c;以下是一些常用参数使用实例和场景: 1. -B参数 在import时候&#xff0c;不产生pyc或者pyo文件: 比如有程序main.py如下: from Hello im…

软件测试/测试开发丨使用ChatGPT自动进行需求分析

简介 在实际工作过程中&#xff0c;常常需要拿到产品的PRD文档或者原型图进行需求分析&#xff0c;为产品的功能设计和优化提供建议。 而使用ChatGPT可以很好地帮助分析和整理用户需求。 实践演练 接下来&#xff0c;需要使用ChatGPT 辅助我们完成需求分析的任务 注意&…

python正则表达式笔记1

最近工作中经常用到正则表达式处理数据&#xff0c;慢慢发现了正则表达式的强大功能&#xff0c;尤其在数据处理工作中&#xff0c;记录下来分享给大家。 一、 正则表达式语法介绍 正则表达式&#xff08;或 RE&#xff09;指定了一组与之匹配的字符串&#xff1b;模块内的函…

数据链路层相关知识

数据链路层的作用 两个设备(同一种数据链路节点)之间进行传递数据 认识以太网 "以太网"是一种技术标准;既包含了数据链路层的内容,也包含了一些物理层的内容.例如:规定了网络拓扑结构,访问控制方式,传输速率等;以太网中的网线必须使用双绞线;传输速率有10M,100M,1…

springboot整合redis-sentinel哨兵模式集群(一)

引入依赖 <!-- redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>redis.clients</groupId><ar…