@requirespermissions注解是什么意思_如何基于spring开发自定义注解实现对接口访问频次限制?...

做JavaWeb的开发的同学们都应该遇到过,客户要求某个接口进行频次的限制,如每秒并发10个,或者短信验证码发送场景,60秒内只允许发送一次。

通常开发的小伙伴们肯定是拿到以上需求在接口逻辑里进行实现,噼里啪啦一顿输出,OK搞定了,很简单。的确,这些需求比较简单,但是,有没有想过,这种频次限制其实是和业务耦合度不高,能不能统一封装,在业务需要的时候直接设置就行了呢?

答案是肯定的。自定义注解来实现就非常的方便,对你的业务接口增加自定义注解,无需修改业务代码即可快速按需完成想要的功能。

第一步:当然是定义一个自定义注解,如RateLimit

8751d2d138080773551ec37205b09bb9.png

定义一个自定义注解RateLimit应用在方法或者类上,并定义相关关键字段,参数Key、频次数、时间、错误提示等。意思就是,在多少时间内,根据参数Key获取的值为判断依据,允许多少频次数的访问,如果超过,那么提示错误提示语,并拒绝访问。

第二步:实现HandlerInterceptor自定义一个拦截器

0a8a5093c97b600ae89904ab4152a2d1.png

在拦截器里重写preHandle,将Object handler转换成HandlerMethod类型传递给自定义的securityManager处理,小伙伴也可以在这个地方直接实现,直接实现代码就不是显得那么高大上了。

第三步:核心处理逻辑

bcd4a0827d06b6f38b7e8cb370c69b8c.png
528099cf24071d8195f5eec147b3ed01.png
059a341a41bc7a3bba9a3db8352708b9.png
efb65b666df05ca8a3b1d4ee52abbeec.png

核心处理方法为handle方法,专门处理类RateLimitHandler。该方法,获取到方法上的注解类RateLimit,并获取到注解类里的关键信息:key()、fromHead()。fromHead为true表示从请求头根据key值获取对应的value值作为唯一标识uuid,否则直接从请求参数里根据key获取唯一标识。获取唯一标识后,调用validateRate方法进行校验是否超过频次,传入uuid,时间、时间单元,当前请求对象。

7cd0889136c782580dbec6a99a421293.png

校验方法,首先根据uuid生成一个内部key,用于区分不同业务,cacheHandler是一个缓存实现,本例中,cacheHandler其实注入的是redis实例,也可以是内存实例。调用cacheHandler自增方法返回一个值,为什么要用自增,是因为考虑并发情况,不能先get再set。如果为1,表示第一次访问,设置一个失效时间,即注解定义的多少时间内,在这个时间过后,自动失效。

最后判断次数是否超过注解类定义的频次数,如果超过,返回false,否则,返回true。到此,自定义注解的实现就结束了。大家疑惑,如果使用起来呢。

第四步:使用,如:60秒内,只允许请求一次(哈哈哈短信验证码使用场景)

e930f396e1e43bf3130a08958589c951.png

OK,就是这么简单,后续有其他相似的业务只需加这个注解,修改不同的时间、限制次数就可以。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值