SpringBoot如何实现一个Redis限流注解,
分享于 点击 47525 次 点评:202
SpringBoot如何实现一个Redis限流注解,
目录
- SpringBoot实现一个Redis限流注解
- 使用步骤
- 1.引入库
- 2.代码实现
- 总结
SpringBoot实现一个Redis限流注解
使用步骤
1.引入库
- 代码如下(示例)
<!-- 引入SpringBoot Aop依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
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<List<AiModelVO>> getAllModel() { return ResultUtils.success(aiModelService.getAllModel()); }
总结
以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持3672js教程。
您可能感兴趣的文章:- Springboot中使用Redisson+AOP+自定义注解实现访问限流与黑名单拦截
- SpringBoot使用自定义注解+AOP+Redis实现接口限流的实例代码
- SpringBoot如何使用自定义注解实现接口限流
用户点评