springboot实现一个redis限流注解
使用步骤
1.引入库
- 代码如下(示例)
org.springframework.boot spring-boot-starter-aop
2.代码实现
- 添加注解
package com.hhh.springai_test.annotation; import java.lang.annotation.elementtype; import java.lang.annotation.retention; import java.lang.annotation.retentionpolicy; import java.lang.annotation.target; @target(elementtype.method) @retention(retentionpolicy.runtime) public @interface redislimiting { int number() default 3; int time() default 60; string message() default "请求过于频繁,请稍后再试"; }
- 新增限流aop实现
package com.hhh.springai_test.aop; import cn.hutool.crypto.digest.md5; import com.hhh.springai_test.annotation.redislimiting; import com.hhh.springai_test.common.errorcode; import com.hhh.springai_test.exception.businessexception; import com.hhh.springai_test.utils.redisutils; import lombok.extern.slf4j.slf4j; import org.aspectj.lang.proceedingjoinpoint; import org.aspectj.lang.annotation.around; import org.aspectj.lang.annotation.aspect; import org.aspectj.lang.reflect.methodsignature; import org.springframework.beans.factory.annotation.autowired; import org.springframework.stereotype.component; import java.lang.reflect.method; import java.lang.reflect.parameter; @aspect @component("redislimitingaspect") @slf4j public class redislimitingaspect { @autowired private redisutils redisutils; @around("@annotation(com.hhh.springai_test.annotation.redislimiting)") // 只拦截带 @redislimiting 的方法 public object redislimiting(proceedingjoinpoint joinpoint) throws throwable { methodsignature signature = (methodsignature) joinpoint.getsignature(); method method = signature.getmethod(); // 直接获取被代理的方法 // 获取 @redislimiting 注解 redislimiting annotation = method.getannotation(redislimiting.class); if (annotation == null) { return joinpoint.proceed(); // 没有注解,直接执行方法 } int limit = annotation.number(); // 限制次数 int expire = annotation.time(); // 过期时间 string message = annotation.message(); log.info("拦截方法: {}, 限流 key: {}, 限流次数: {}, 过期时间: {} 秒", method.getname(), limit, expire); // 执行限流逻辑 boolean isallowed = checkredislimiting(method, joinpoint.getargs(), limit, expire); if (!isallowed) { throw new businessexception(errorcode.busy_error,message); } return joinpoint.proceed(); // 执行原方法 } private boolean checkredislimiting(method method, object[] args, int limit, int expire) { // 生成 redis key string rediskey = generaterediskey(method, args); // 查询 redis 是否存在 object o = redisutils.get(rediskey); if (o == null) { redisutils.setex(rediskey, 1, expire); // 初始值设为1,并设置过期时间 return true; } else { int count = integer.parseint(o.tostring()); if (count >= limit) { return false; // 超过限制 } else { redisutils.increment(rediskey, 1); // 递增计数 return true; } } } private string generaterediskey(method method, object[] args) { stringbuilder builder = new stringbuilder(); builder.append(method.getdeclaringclass().getname()).append(":").append(method.getname()).append(":"); parameter[] parameters = method.getparameters(); for (int i = 0; i < parameters.length; i++) { builder.append(parameters[i].getname()).append("=").append(args[i]).append("&"); } return md5.create().digesthex16(builder.tostring()); // 生成唯一 redis key } }
- 实现代码的拦截
@getmapping("/getallmodel") @redislimiting(number = 3, time = 60,message = "不要再请求我的获取aimodel方法了") public baseresponse> getallmodel() { return resultutils.success(aimodelservice.getallmodel()); }
总结
以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
海报
121