redis命令Incr做计数器 + 切点切面
Redis Incr 命令将 key 中储存的数字值增一。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
package com.example.apidemo.config.aspect; import com.example.apidemo.redis.LocalCache;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Objects;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import java.util.Date;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; @Aspect
@Component
public class DoneTimeAspect { @Autowired
private LocalCache localCache; /**
* 当方法符合切点规则不符合环绕通知的规则时候,执行的顺序如下
* @Before → @After→ @AfterRunning (如果有异常→@AfterThrowing)
*
* 当方法符合切点规则并且符合环绕通知的规则时候,执行的顺序如下
* @Around → @Before → @Around → @After执行 ProceedingJoinPoint.proceed() 之后的操作→@AfterRunning(如果有异常→@AfterThrowing)
*/ @Before("execution (* com.example.apidemo.controller.*.*(..))")
public void before(JoinPoint joinPoint) throws Exception {
System.out.println("======前置通知--拦截配置的package的controller:" + Arrays.toString(joinPoint.getArgs()) + LocalDateTime.now()); //最简单的接口重复请求处理方法
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String sessionId = attributes.getSessionId(); // 用户请求唯一标识sessionId
String uri = attributes.getRequest().getServletPath(); // 用户请求的uri
String key = sessionId + "-" + uri; // 针对用户对应接口的唯一key
System.out.println("key==="+ key + LocalDateTime.now());
Object object = localCache.getCache(key); // 将生成的key存储在redis中,每次请求一次就增加一次
System.out.println("object==="+ object + "==" + LocalDateTime.now());
if (Objects.isNull(object) || Integer.parseInt(object.toString()) <=2 ) {
localCache.putIncrKey(key, 1L); //设置2分钟 过期
return;
}
if (Integer.parseInt(object.toString()) >2) {
throw new Exception("接口在2分钟内重复请求超过2次"); //再写一个全局ExceptionHandler,返回给前端 }
} @Around("execution (* com.example.apidemo.controller.*.*(..)) && @annotation(doneTime))")
public Object around(ProceedingJoinPoint joinPoint, DoneTime doneTime) throws Throwable { System.out.println("======环绕通知--:"+ Arrays.toString(joinPoint.getArgs()));
if (doneTime.param().equals("IndexController")) {
return "切面直接拦截==IndexController";
}
Object o = joinPoint.proceed(); //joinPoint.proceed()会继续走切面所在的方法
System.out.println("切面走proceed方法结束时间是:"+new Date()) ;
return o;
} }
@Component
@Slf4j
public class LocalCache { @Autowired
private StringRedisTemplate stringRedisTemplate;
public void putIncrKey(String key, Long value) {
Long num = stringRedisTemplate.opsForValue().increment(key, value);
log.info("increment===key|{},num|{},time|{}", key, num, LocalDateTime.now());
//increment 命令传入value 为1就加1, 为5就加5
if (num != null) {
stringRedisTemplate.expire(key,2, TimeUnit.MINUTES);
}
}
}
redis命令Incr做计数器 + 切点切面的更多相关文章
- Redis SWAPDB 命令背后做了什么
Redis SWAPDB 命令背后做了什么 目录 Redis SWAPDB 命令背后做了什么 0x00 摘要 0x01 SWAPDB 基础 1.1 命令说明 1.2 演示 0x02 预先校验 0x03 ...
- Redis详细讲解(Redis原理,Redis安装,Redis配置,Redis使用,Redis命令)
一.Redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发 ...
- Redis命令大全&中文解释&在线测试命令工具&在线中文文档
在线测试命令地址:http://try.redis.io/ 官方文档:http://redis.io/commands http://redis.io/documentation Redis 命令参考 ...
- Redis命令
redis的常用命令主要分为两个方面.一个是键值相关命令.一个是服务器相关命令(redis-cli进入终端) 1.键值相关命令 keys * 取出当前所有的key exists name 查看n是否有 ...
- 最全面的Redis命令行查阅手册(收藏查看)
Redis是用C语言实现的,一般来说C语言实现的程序“距离”操作系统更近,执行速度相对会更快. Redis使用了单线程架构,预防了多线程可能产生的竞争问题. 作者对于Redis源代码可以说是精打细磨, ...
- 基于Redis的INCR实现一个限流器
模式:计数器 计数器是 Redis 的原子性自增操作可实现的最直观的模式了,它的想法相当简单:每当某个操作发生时,向 Redis 发送一个 INCR 命令. 比如在一个 web 应用程序中,如果想知道 ...
- redis命令大全参考手册
redis功能强大,支持数据类型丰富,以下是redis操作命令大全,基本上涵盖了redis所有的命令,并附有解释说明,大家可以收藏.参考,你一定要知道的是:redis的key名要区分大小写,在redi ...
- redis实战笔记(3)-第3章 Redis命令
第3章 Redis命令 本章主要内容 字符串命令. 列表命令和集合命令 散列命令和有序集合命令 发布命令与订阅命令 其他命令 在每个不同的数据类型的章节里, 展示的都是该数据类型所独有的. 最 ...
- redis命令_INCR
INCR key 将 key 中储存的数字值增一. 如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作. 如果值包含错误的类型,或字符串类型的值不能表示为数字,那 ...
- 深入Redis命令的执行过程
深入Redis命令的执行过程 Redis 服务器: Redis 服务器实现与多个客户端的连接,并处理这些客户端发送过来的请求,同时保存客户端执行命令所产生的数据到数据库中.Redis 服务器依靠资源管 ...
随机推荐
- 【Android】无法通过drawable下的selector类型改变背景颜色?
举例 我在darwable目录下创建了selector文件,并设置了如下内容 <?xml version="1.0" encoding="utf-8"?& ...
- Opencv实例练习
实例所用的函数可在另一篇文章查询: https://www.cnblogs.com/Zhouce/p/17867164.html 1.图像读取 1 import cv2 # 引入opencv库 2 ...
- .NET开源且好用的权限工作流管理系统
前言 系统权限管理.工作流是企业应用开发中很常见的功能,虽说开发起来难度不大,但是假如从零开始开发一个完整的权限管理和工作流平台的话也是比较耗费时间的.今天推荐一款.NET开源且好用的权限工作流管理系 ...
- SpringCore完整学习教程5,入门级别
本章从第6章开始 6. JSON Spring Boot提供了三个JSON映射库的集成: Gson Jackson JSON-B Jackson是首选的和默认的库. 6.1. Jackson 为Jac ...
- [2020-2021 集训队作业] Tom & Jerry
题目背景 自选题 by ix35 题目描述 给定一张包含 \(n\) 个顶点和 \(m\) 条边的 无向连通图,Tom 和 Jerry 在图上进行了 \(q\) 次追逐游戏. 在第 \(i\) 次游戏 ...
- C# 从代码入门 Mysql 数据库事务
目录 生成数据库数据 Mysql 数据库事务基础 数据库的并发一致性问题 数据库事务的隔离级别 BeginTransaction() 和 TransactionScope 的区别 BeginTrans ...
- 聊聊流式数据湖Paimon(四)
Partial Update 数据打宽 通过不同的流写不同的字段,打宽了数据的维度,填充了数据内容:如下所示: --FlinkSQL参数设置 set `table.dynamic-table-opti ...
- ElasticSearch之cat repositories API
命令样例如下: curl -X GET "https://localhost:9200/_cat/repositories?v=true&pretty" --cacert ...
- 【云原生 | Kubernetes 系列】—K8S部署RocketMQ集群(双主双从+同步模式)
[云原生 | Kubernetes 系列]-K8S部署RocketMQ集群(双主双从+同步模式) 版权 本文为云录原创文章,转载无需和我联系,但请注明来自云录 https://www.yunzhuan ...
- 前端 Git 使用约定
前端 Git 使用约定 背景 开发前端项目,有以下困惑: 使用哪个分支开发,哪个分支发布 修复线上bug的流程是什么,如何避免修复完了下次却又出现了 cms分支有十多个,是否都有用 如何快速找到之前某 ...