DistributedLock.class
/**
* @author zst
* @description 分布式锁注解
* @date 2023/6/3 0003 11:41
* @mail 804633234@qq.com
*/
import java.lang.annotation.*;
import java.util.concurrent.TimeUnit;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {
/**
* 锁的名称,必填
*/
String name();
/**
* 锁的持有时间,单位秒,默认 10 秒
*/
long timeout() default 10000;
DistributedLockAspect.class
package com.chainlan.base.common.annotation.achieve;
import com.chainlan.base.common.annotation.DistributedLock;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
/**
* @author zst
* @description
* @date 2023/6/3 0003 11:45
* @mail 804633234@qq.com
*/
@Aspect
@Component
public class DistributedLockAspect {
private static final Logger log = LoggerFactory.getLogger(DistributedLockAspect.class);
@Resource
private RedisTemplate redisTemplate;
@Around("@annotation(distributedLock)")
public Object around(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) throws Throwable {
//锁名
String lockName = distributedLock.name();
//超时
long timeout = distributedLock.timeout();
log.info("************分布式注解锁***********************{},{}",lockName,timeout);
Boolean reentrant= this.acquireLock(lockName,lockName,timeout);
if (!reentrant) {
throw new RuntimeException("稍等一会");
}
// 执行方法
Object result = null;
try {
result = joinPoint.proceed();
} finally {
log.info("************分布式注解锁finally***********************{},{}",lockName,timeout);
this.releaseLock(lockName,lockName);
}
return result;
}
//加锁
public boolean acquireLock(String lockKey, String requestId, long expireTime) {
Boolean result = redisTemplate.opsForValue().setIfAbsent("lock:"+lockKey, requestId, expireTime, TimeUnit.MILLISECONDS);
return result != null && result;
}
//解锁
public void releaseLock(String lockKey, String requestId) {
Object currentValue = redisTemplate.opsForValue().get("lock:"+lockKey);
if (currentValue != null && currentValue.toString().equals(requestId)) {
redisTemplate.delete("lock:"+lockKey);
}
}
}
使用
@DistributedLock(name="test")
public AjaxResult test(@RequestBody test)
{
}