当前位置 : 主页 > 网络编程 > 其它编程 >

基于注解的redis分布式锁的简单实现

来源:互联网 收集:自由互联 发布时间:2023-07-02
基于注解的redis分布式锁的简单实现-分布式锁的应用场景还是比较多的,然后手头的项目没有有效的封装,然后忙里偷闲,简单封装了一下分布式锁的实现方式还是很多,比较多的肯定
基于注解的redis分布式锁的简单实现-分布式锁的应用场景还是比较多的,然后手头的项目没有有效的封装,然后忙里偷闲,简单封装了一下分布式锁的实现方式还是很多,比较多的肯定就是re

分布式锁的应用场景还是比较多的,然后手头的项目没有有效的封装,然后忙里偷闲,简单封装了一下

分布式锁的实现方式还是很多,比较多的肯定就是redis和zk了,现有的项目只有redis,所以以下的分布式锁是基于redis实现的了。直接上代码吧@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface RedisLock { // 支持SPEL表达式和普通的key String[] keys(); // 等待获取锁的时间 long timeout() default 3000L;}/** * 开启redis分布式锁注解 */@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@ImportAutoConfiguration({LockAop.class})public @interface EnableRedisLock {}@Order(Integer.MIN_VALUE)@Aspectpublic class LockAop { private static Logger logger = LoggerFactory.getLogger(LockAop.class); public LockAop(RedissonClient redissonClient) { this.redissOnClient= redissonClient; logger.info("LockAop 初始化完成!"); } @Pointcut("@annotation(com.bosssoft.nontax3.saas.billCollection.collect.api.common.anno.RedisLock)") public void pointCut() { } private RedissonClient redissonClient; //获取被拦截方法参数名列表(使用Spring支持类库) ASM机制 故定义为常量 private static final LocalVariableTableParameterNameDiscoverer U = new LocalVariableTableParameterNameDiscoverer(); //使用SPEL进行key的解析 线程安全所以可复用 private static final ExpressionParser PARSER = new SpelExpressionParser(); @Around("pointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { RLock lock = null; boolean flag = false; try { MethodSignature signature = (MethodSignature) point.getSignature(); Method method = signature.getMethod(); RedisLock redisLock = method.getAnnotation(RedisLock.class); final String[] keys = redisLock.keys(); final long timeout = redisLock.timeout(); if (keys.length > 0) { final String prefix = getPrefix(keys, method, point.getArgs()); lock = redissonClient.getLock(prefix); final long l = System.currentTimeMillis(); while (true) { // 尝试获取锁,获取失败 等待一会 flag = lock.tryLock(); if (flag) { break; } // 等待一会 不要尝试那么快 sleep(); final long j = System.currentTimeMillis(); if (j - l > timeout) { break; } } } if (flag) { return point.proceed(); } else { throw new BusinessException(LOCK_ERROR); } } finally { if (flag } } } catch (Exception e) { logger.error("lock解锁失败", e); } } } } private void sleep() { try { Thread.sleep(100L); } catch (InterruptedException e) { logger.error("中断异常", e); } } private String getPrefix(String[] keys, Method method, Object[] args) { StringBuilder builder = new StringBuilder(); for (String key : keys) { if (key.startsWith("#")) { builder.append(parseKey(key, method, args)).append(":"); } else { builder.append(key).append(":"); } } return builder.toString(); } /** * 获取spel的具体值 * * @return 具体的前缀 */ private String parseKey(String key, Method method, Object[] args) { if (StringUtils.isEmpty(key)) { return null; } String[] paraNameArr = U.getParameterNames(method); //SPEL上下文 StandardEvaluationContext cOntext= new StandardEvaluationContext(); //把方法参数放入SPEL上下文中 for (int i = 0; i

只实现了一些基本功能,然后使用了Spring的spel表达式,接来下来看看使用吧

@RedisLock(keys = {"#sortTransfer.agencyIdCode","#sortTransfer.directoryCode","save"})public void saveData(SortTransfer sortTransfer) { //Do something、、、}

spel表达式可以直接解析,这样使用就很便利了。

【文章原创作者:阿里云代理 http://www.558idc.com/aliyun.html处的文章,转载请说明出处】
上一篇:Debian7安装Emacs24.4
下一篇:没有了
网友评论