首页 > 数据库 >SpringBoot 自定义注解,轻松实现 Redis 分布式锁

SpringBoot 自定义注解,轻松实现 Redis 分布式锁

时间:2022-11-13 17:24:31浏览次数:42  
标签:SpringBoot 自定义 Redis prefix expire key test reqFastLimit String

1.自定义注解类

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ReqFastLimit {
    //redis key
    String key() default "";
    //过期时间 单位秒
    long expire() default 60L;
  // 前缀
    String prefix() default "";
}

2.定义切面

@Aspect
@Component
@Slf4j
@SuppressWarnings("ALL")
public class ReqFastHandler {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private HttpServletRequest request;

    @Around(("@annotation(reqFastLimit)"))
    public Object around(ProceedingJoinPoint joinPoint, ReqFastLimit reqFastLimit) throws Throwable {
        String requestURI = request.getRequestURI();
        String keySpel = reqFastLimit.key();
        long expire = reqFastLimit.expire();
        String prefix = reqFastLimit.prefix();
        Object[] args = joinPoint.getArgs();
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        //获取被拦截方法参数名列表(使用Spring支持类库)
        LocalVariableTableParameterNameDiscoverer localVariableTable = new LocalVariableTableParameterNameDiscoverer();
        String[] paraNameArr = localVariableTable.getParameterNames(method);
        //使用SPEL进行key的解析
        ExpressionParser parser = new SpelExpressionParser();
        //SPEL上下文
        StandardEvaluationContext context = new StandardEvaluationContext();
        //把方法参数放入SPEL上下文中
        for (int i = 0; i < paraNameArr.length; i++) {
            context.setVariable(paraNameArr[i], args[i]);
        }
        String key = null;
        // 使用变量方式传入业务动态数据
        if (keySpel.matches("^#.*.$")) {
            String[] split = keySpel.split(",");
            for (String s : split) {
                if (key == null) {
                    key = parser.parseExpression(s).getValue(context, String.class);
                } else {
                    key = key + ":" + parser.parseExpression(s).getValue(context, String.class);
                }
            }
        }
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(prefix + key, key, expire, TimeUnit.SECONDS);
            if (!result) {
                log.info("key={}", prefix + key);
                throw new Exception("您手速真快,慢点吧!");
            }
            return joinPoint.proceed();
        } catch (CustomException e) {
            throw e;
        } finally {
          //代码逻辑执行完释放锁
            redisTemplate.delete(prefix + key);
        }

    }

3.注解使用

    @ReqFastLimit(key = "#test.orderNo,#test.channo", expire = 3, prefix = "test")
    public ResultVo test(@RequestBody @Valid Test test) {
        return testService.test(test);
    }

4.效果

 

标签:SpringBoot,自定义,Redis,prefix,expire,key,test,reqFastLimit,String
From: https://www.cnblogs.com/blackCatFish/p/16886342.html

相关文章

  • springboot09(condition-自动配置02)
    一、在前面condition-01中存在许多问题,比如配置烦琐,查找固定死板等等二、这个condition-自动配置02,直接使用springboot给我们的配置来更好的使用condition三、拿proper......
  • springboot集成redis
    1、单机Redis1、导入对应的包<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redi......
  • redis缓存雪崩
              代码实现:互斥锁packagecom.hmdp.utils;importcn.hutool.core.util.BooleanUtil;importcn.hutool.core.util.StrUtil;importcn.hutool.......
  • 一次SpringBoot版本升级,引发的血案
    前言最近项目组升级了SpringBoot版本,由之前的2.0.4升级到最新版本2.7.5,却引出了一个大Bug。到底是怎么回事呢?1.案发现场有一天,项目组的同事反馈给我说,我之前有个接口在......
  • 自定义字符串排序
    题目给定两个字符串order和s。order的所有单词都是唯一的,并且以前按照一些自定义的顺序排序。对s的字符进行置换,使其与排序的 order 相匹配。更具体地说,如果......
  • 791. 自定义字符串排序
    791.自定义字符串排序给定两个字符串order和s。order的所有单词都是唯一的,并且以前按照一些自定义的顺序排序。对s的字符进行置换,使其与排序的 order 相匹配......
  • Springboot中-全局异常处理类用法示例
    使用springboot搭建web项目的时候,一般都会添加一个全局异常类,用来统一处理各种自定义异常信息,和其他非自定义的异常信息,以便于统一返回错误信息。下面就是简单的示例......
  • 791. 自定义字符串排序 ----- 自定义sort、权值排序、计数排序
    给定两个字符串order和s。order的所有单词都是唯一的,并且以前按照一些自定义的顺序排序。对s的字符进行置换,使其与排序的 order 相匹配。更具体地说,如果在 or......
  • SpringBoot实现mysql主从复制
    导入依赖<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.0.0-RC1</v......
  • redis中缓存穿透
         代码实现 //Stringkey=CACHE_SHOP_KEY+id;////1从缓存中查询上铺缓存//StringshopJson=stringRedisTemplate.opsForVa......