一、引入maven依赖
记得自行找到对应的版本
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
二、创建注解
package com.bop.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;
/**
* 分布式锁
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {
/**
* 分布式锁key前缀
*/
String keyPrefix() default "";
/**
* 获取锁等待时间(默认两秒,还没获取到锁即放弃)
*/
long waitTime() default 2;
/**
* 过期时长,防止一直占用锁
*/
long expire() default 10;
/**
* 过期时长单位
*/
TimeUnit timeUnit() default TimeUnit.SECONDS;
}
三、实现注解(AOP)
package com.bop.aspect;
import cn.hutool.core.util.StrUtil;
import com.bop.annotation.DistributedLock;
import com.bop.exception.BaseException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 分布式锁注解实现
*
* @author neal.armstrong
* @version 1.0
* @since 2021/7/20 17:11
*/
@Aspect
@Component
@AllArgsConstructor
@Order(1)
@Slf4j
public class DistributedLockAspect {
private final RedissonClient redissonClient;
@Around("@annotation(distributedLock)")
public Object lock(ProceedingJoinPoint proceedingJoinPoint, DistributedLock distributedLock) {
Signature signature = proceedingJoinPoint.getSignature();
String key;
if (StrUtil.isNotBlank(distributedLock.keyPrefix())) {
key = String.format("lock:%s:%s", distributedLock.keyPrefix(), signature.getDeclaringTypeName());
} else {
key = String.format("lock:%s", signature.getDeclaringTypeName());
}
RLock lock = redissonClient.getLock(key);
boolean hasLock = false;
try {
hasLock = lock.tryLock(distributedLock.waitTime(), distributedLock.expire(), distributedLock.timeUnit());
if (hasLock) {
return proceedingJoinPoint.proceed();
}
} catch (Throwable throwable) {
log.error(throwable.getMessage());
throw BaseException.serviceErr(throwable.getMessage());
} finally {
if (hasLock) {
lock.unlock();
}
}
throw BaseException.serviceErr("获取分布式锁失败");
}
}
四、使用注解
可用于service、controller层