1.Redisson aop类
@Component
@Aspect
public class RedisLockAspectj {
private static final Logger log = LoggerFactory.getLogger(RedisLockAspectj.class);
@Resource
RedissonClient redissonClient;
public RedisLockAspectj() {
}
@Pointcut("@annotation(com..*******.LockCheck)")
private void pointCutMethod() {
}
@Around("pointCutMethod() && args(baseLockDTO, ..)")
public Object around(ProceedingJoinPoint point, BaseLockDTO baseLockDTO) throws Throwable {
String redisLockKey = baseLockDTO.getRedisLockKey();
log.info("开始加锁,redisLockKey:{}", redisLockKey);
RLock lock = redissonClient.getLock(redisLockKey);
boolean flag;
if (Objects.equals(baseLockDTO.getIsRenewal(), 1)) {
flag = lock.tryLock();
} else {
flag = lock.tryLock(baseLockDTO.getWaitTime(), baseLockDTO.getLeaseTime(), baseLockDTO.getUnit());
}
log.info("是否获取加锁,flag:{}", flag);
Object result;
try {
if (!flag) {
log.info("任务正在执行无须重复操作,任务key:{}", redisLockKey);
throw new ServiceException(ResultCodeEnum.LOCK_CODE.getCode(), "操作重复,请稍后再试");
}
result = point.proceed();
} finally {
if (flag && lock.isHeldByCurrentThread()) {
log.info("开始释放锁,redisLockKey:{}", redisLockKey);
lock.unlock();
}
}
return result;
}
}
2.实体诶需要继承此类
@ApiModel
public class BaseLockDTO {
private static final Logger log = LoggerFactory.getLogger(BaseLockDTO.class);
@ApiModelProperty(
value = "是否续期 0否 1是。默认1",
hidden = true
)
private Integer isRenewal = 1;
@ApiModelProperty(
value = "获取锁的时间。默认60s",
hidden = true
)
private long waitTime = 60L;
@ApiModelProperty(
value = "锁的有效期默认-1",
hidden = true
)
private long leaseTime = -1L;
@ApiModelProperty(
value = "单位。默认秒",
hidden = true
)
private TimeUnit unit;
@JsonIgnore
public String getRedisLockKey() throws Exception {
Field[] fields = this.getClass().getDeclaredFields();
Field[] var2 = fields;
int var3 = fields.length;
for(int var4 = 0; var4 < var3; ++var4) {
Field field = var2[var4];
LockKey lockKeyAnnotation = (LockKey)field.getDeclaredAnnotation(LockKey.class);
if (Objects.nonNull(lockKeyAnnotation)) {
field.setAccessible(true);
Object resultValue = field.get(this);
log.info("反射获取到lockKey:{}", resultValue);
if (Objects.isNull(resultValue)) {
throw new BusinessException("获取redisLockKey异常");
}
if (StringUtils.isNotBlank(lockKeyAnnotation.type())) {
return String.format("%s:%s:%s", lockKeyAnnotation.prefix(), lockKeyAnnotation.type(), resultValue);
}
return String.format("%s:%s", lockKeyAnnotation.prefix(), resultValue);
}
}
throw new BusinessException("获取LockKey失败");
}
3.aop的注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LockCheck {
}
4.锁的lockkey注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LockKey {
String prefix() default "";
String type() default "";
}
5.案例
@Data
public class MyLockDTO extends BaseLockDTO {
// rediskey =prefix +type
@LockKey(prefix = "***",type = "**")
private String lockKey;// 存对应的业务代码
}
MyLockDTO lockDTO = new MyLockDTO ();
lockDTO.setLockKey(“lockkey”);
function(lockDTO);
@LockCheck
@Override
public void function(MyLockDTO lockDTO) {}