Java中动态修改注解的值

1. 描述

部分场景需要动态修改注解的值。例如,我们使用自定义注解控制接口流量,如果需要动态修改流量值,可以使用反射的方法实现。

2. 步骤

  • 获取注解
  • 从注解中获取memberValues属性(map)
  • 使用put方法更新对象的值

3. 代码实现

该部分代码主要是基于流量控制的功能demo,使用反射动态修改@RateLimit注解达到动态修改流量的目的。此章节节选了反射修改值的代码予以分享。

3.1 主工具类

import com.hz.common.aop.limit.RateLimit;import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Map;/*** @author pp_lan* @date 2024/2/3*/
public class ReflectUtils {private ReflectUtils() {}public static void dynamicLocation(RateLimit rateLimit, String fileName, Object fieldValue) throws IllegalAccessException, NoSuchFieldException {if (rateLimit == null) {return;}InvocationHandler invocationHandler = Proxy.getInvocationHandler(rateLimit);Class<? extends InvocationHandler> aClass = invocationHandler.getClass();Field memberValues = aClass.getDeclaredField("memberValues");memberValues.setAccessible(true);Map<String, Object> menberValueMap = (Map<String, Object>) memberValues.get(invocationHandler);menberValueMap.put(fileName, fieldValue);}
}

3.2 依赖

3.2.1 RateLimit

import java.lang.annotation.*;/*** @author pp_lan*/
@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {/*** 名称** @return*/String name();/*** 每分钟限流数量** @return*/int limitNum();}

3.2.2 切面处理

切面中需要动态获取注解

@Component
public class RateLimitAspect {private static final Logger LOGGER = LoggerFactory.getLogger(RateLimitAspect.class);private ConcurrentHashMap<String, RateLimiter> limitMap = new ConcurrentHashMap<>();@Pointcut("@annotation(com.hz.common.aop.limit.RateLimit) && @annotation(rateLimit)")public void pointCut(RateLimit rateLimit){}@Around(value = "pointCut(rateLimit)")public Object around(ProceedingJoinPoint joinPoint, RateLimit rateLimit) throws Throwable {// 此处动态获取注解值取代初始化的RateLimit值Object target = joinPoint.getTarget();MethodSignature sig = (MethodSignature) joinPoint.getSignature();Method currentMethod = target.getClass().getMethod(sig.getName(), sig.getParameterTypes());RateLimit newRateLimit = currentMethod.getAnnotation(RateLimit.class);LOGGER.info("[限流器{}]{}", newRateLimit.name(), newRateLimit.limitNum());boolean isLimited = limitByKey(newRateLimit.name(), newRateLimit.limitNum());if (isLimited) {throw new RateLimitException(String.format("【限流了】%s", newRateLimit.name()));}return joinPoint.proceed();}/*** 是否被限流** @param key* @param limitNum* @return*/private boolean limitByKey(String key, Integer limitNum) {...}}

3.3 使用

5-7行获取注解,并修改注解中属性的值

@RequestMapping("/updateLimitRate")
public Response editLimitRate(Integer methodType, Integer limitNum) throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException {String methodName = methodType == 1 ? "queryAllUser": "test";Method method = UserService.class.getMethod(methodName);RateLimit annotation = method.getAnnotation(RateLimit.class);ReflectUtils.dynamicLocation(annotation, "limitNum", limitNum);return Response.ok();
}

4. 效果

4.1 初始化的桶大小

4.2 限流提示

4.3 动态更改流量值

4.4 重新访问

不再限流,接口可以继续正常访问了。

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

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

相关文章

MySQL事务原理的分析

1.事务 并发连接下考虑事务。 事务的本质是并发控制的单元&#xff0c;是用户定义的一个操作序列。这些操作要么都做&#xff0c;要么都不做&#xff0c;是一个不可分割的工作单位。 事务控制语句 ACID特性 原子性&#xff1a;要么都做&#xff0c;要走么都不做。在事务执…

原型中之find()-查找满足条件的第一个元素,并返回该元素的值

array.find(callback(element[, index[, array]])[, thisArg]) callback&#xff1a;必需。要在数组中每个元素上执行的函数。 element&#xff1a;必需。当前正在处理的数组元素。 index&#xff1a;可选。正在处理的元素的索引。 array&#xff1a;可选。调用该方法的数组…

【Java程序设计】【C00247】基于Springboot的农机电招平台(有论文)

基于Springboot的农机电招平台&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的农机电招平台 本系统分为系统功能模块、管理员功能模块、农机机主功能模块以及使用者功能模块。 系统功能模块&#xff1a;农机电招…

电力升级改造,我发现了这种配电柜高效技巧!

在当今数字化和智能化的时代&#xff0c;电力作为企业和机构运转的生命线&#xff0c;其高效、可靠、安全的管理变得尤为重要。 因此&#xff0c;为了应对不断增长的电力需求和提升电力设备的运行水平&#xff0c;配电柜监控系统应运而生。 客户案例 制造业企业 济宁某企业面…

8868体育助力意甲尤文图斯俱乐部 帮助球队签订新合同

意甲的尤文图斯俱乐部是8868合作体育球队之一&#xff0c;根据意大利媒体的消息&#xff0c;尤文图斯已经决定和费德里科-基耶萨续约&#xff0c;这名球员已经开始思考他的将来了。 费德里科-基耶萨今年26岁&#xff0c;他和尤文图斯的合约到2025年6月30号就结束了。他知道很多…

Jmeter 基于Docker 实现分布式测试

基于Docker 实现分布式测试 制作Jmeter基础镜像制作工作节点镜像启动工作节点启动控制节点遇到的问题 使用Docker 部署Jmeter非常方便&#xff0c;可以省略软件的安装以及配置&#xff0c;比如jdk、jmeter。需要部署多个工作节点可以节省时间。 控制节点&#xff08;Master-主节…

yo!这里是单例模式相关介绍

目录 前言 特殊类设计 只能在堆上创建对象的类 1.方法一&#xff08;构造函数下手&#xff09; 2.方法二&#xff08;析构函数下手&#xff09; 只能在栈上创建对象的类 单例模式 饿汉模式实现 懒汉模式实现 后记 前言 在面向找工作学习c的过程中&#xff0c;除了基本…

隐写术:隐藏信息的秘密艺术

一、引言 隐写术&#xff0c;这个充满神秘色彩的词汇&#xff0c;似乎让我们回到了间谍和秘密特工的时代。但实际上&#xff0c;隐写术在现代社会仍然有着广泛的应用&#xff0c;例如在军事、情报、商业等领域。本文将带你走进隐写术的世界&#xff0c;探索它的原理、应用和防…

大模型增量预训练新技巧:解决灾难性遗忘

大家好&#xff0c;目前不少开源模型在通用领域具有不错的效果&#xff0c;但由于缺乏领域数据&#xff0c;往往在一些垂直领域中表现不理想&#xff0c;这时就需要增量预训练和微调等方法来提高模型的领域能力。 但在领域数据增量预训练或微调时&#xff0c;很容易出现灾难性…

git 如何修改仓库地址

问题背景&#xff1a;组内更换大部门之后&#xff0c;代码仓的地址也迁移了&#xff0c;所以原来的git仓库地址失效了。 虽然重新建一个新的文件夹&#xff0c;再把每个项目都git clone一遍也可以。但是有点繁琐&#xff0c;而且有的项目本地还有已经开发一半的代码&#xff0c…

遗失的源代码之回归之路的探索与实践

背景 最近比较突然被安排接手一个项目,该项目的情况如下 原生和RN结合的混合开发模式组件化开发,有很多基础组件以及业务组件但是在梳理项目依赖时发现了个别组件源码不全的情况,于是写了个cli用于对比两个版本产物文件,生成差异结果以便于快速进行源码找回恢复。 结果如下…

【lesson9】高并发内存池Page Cache层释放内存的实现

文章目录 Page Cache层释放内存的流程Page Cache层释放内存的实现 Page Cache层释放内存的流程 如果central cache释放回一个span&#xff0c;则依次寻找span的前后page id的没有在使用的空闲span&#xff0c;看是否可以合并&#xff0c;如果合并继续向前寻找。这样就可以将切…

05、全文检索 -- Solr -- Solr 全文检索之图形界面的文档管理(文档的添加、删除,如何通过关键字等参数查询文档)

目录 Solr 全文检索之文档管理添加文档使用 JSON 添加文档&#xff1a;使用 XML 添加文档: 删除文档使用 JSON 删除文档&#xff1a;使用 XML 删除文档&#xff1a; 查询文档查询文档的详细参数fq&#xff08;Filter Query&#xff09;&#xff1a;过滤sort&#xff1a;排序sta…

[Linux 进程(六)] 写时拷贝 - 进程终止

文章目录 1、写时拷贝2、进程终止2.1 进程退出场景2.1.1 退出码2.1.2 错误码错误码 vs 退出码2.1.3 代码异常终止引入 2.2 进程常见退出方法2.2.1 exit函数2.2.2 _exit函数 本片我们主要来讲进程控制&#xff0c;讲之前我们先把写时拷贝理清&#xff0c;然后再开始讲进程控制。…

[office] 在Excel2010中设定某些单元格数据不参与排序的方法介绍 #其他#知识分享#笔记

在Excel2010中设定某些单元格数据不参与排序的方法介绍 在Excel中排序&#xff0c;相信大家都会了&#xff0c;直接将一组数据按照从小到大或者从大到小进行排序&#xff0c;但是&#xff0c;现在要求我们规定其中几组数据不进行排序&#xff0c;只排序其余的部分。又该如何操作…

ruoyi(若依)(el-menu也可参考)菜单栏过长显示省略号才显示气泡

一、背景 若依前后端分离的版本&#xff0c;新版本中优化了菜单名称过长悬停显示标题&#xff0c;但是是悬浮所有长度大于5的标题。可以查看提交记录&#xff1a;https://gitee.com/y_project/RuoYi-Cloud/commit/99932d91c0144da9f34f5bb05683cc0b86303217 但是我希望是只悬浮…

VC++中使用OpenCV绘制直线、矩形、圆和文字

VC中使用OpenCV绘制直线、矩形、圆和文字 在VC中使用OpenCV绘制直线、矩形、圆和文字非常简单&#xff0c;分别使用OpenCV中的line、rectangle、circle、putText这四个函数即可。具体可以参考OpenCV官方文档&#xff1a;https://docs.opencv.org/4.x/index.html 下面的代码展…

nodejs express中使用连接池或者MySQL链接数据库出现Cannot read property ‘query‘ of undefined报错

1.如果你已经排除了数据库的启动状态原因和本地服务是否启动的原因 2.不妨看看你是否没有排查其他的数据库&#xff0c;我就是一直在排查第一个主数据库&#xff0c;却忘了我还连接了第二个数据库&#xff0c;就是第二个数据库的原因&#xff0c;出现这个错误。 3.我们可以通…

「 CISSP学习笔记 」08. 安全运营

该知识领域涉及如下考点&#xff0c;具体内容分布于如下各个子章节&#xff1a; 理解并遵守调查执行记录和监控活动执行配置管理 (CM)&#xff08;例如&#xff0c;预配、基线、自动化&#xff09;应用基本的安全操作概念应用资源保护执行事故管理执行和维护检测和预防措施实施…

我们使用的IPv4耗尽(We‘re running out of IPv4)

IPv4(Internet Protocol version 4)是互联网上使用最广泛的网络层协议之一,于1981年在 RFC 791 中发布,它定义了 32 位的IP地址结构和基本的协议操作。 由于 IPv4 使用 32 位的地址,因此只有四十亿(4,294,967,296,2^32)个地址。 这就导致随着地址不断被分配,IPv4 地…