八股八股注解实现分布式锁
Jaron注解实现分布式锁
1、原始写法
我们平常使用redisson的分布式锁是怎么做的?
是不是基本都用的这个模板,既然是模板,那为何不把他抽出来呢?
1 2 3 4 5 6 7 8 9 10
| boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS); if (res) { try { ...业务代码 } finally { lock.unlock(); } }
|
2、抽出分布式锁工具类
我们可以抽出一个LockService方法,把锁的模板写在方法里,调用的时候只需要指定key,把锁内的代码块用supplier函数传进来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @Service @Slf4j public class LockService {
@Autowired private RedissonClient redissonClient;
public <T> T executeWithLock(String key, int waitTime, TimeUnit unit, SupplierThrow<T> supplier) throws Throwable { RLock lock = redissonClient.getLock(key); boolean lockSuccess = lock.tryLock(waitTime, unit); if (!lockSuccess) { throw new BusinessException(CommonErrorEnum.LOCK_LIMIT); } try { return supplier.get(); } finally { lock.unlock(); } } }
|
3、注解实现分布式锁
其实锁工具类已经是核心功能代码了,用注解只是为了使用方便。就像很多底层sdk,都是有接口调用的方法来实现核心功能,然后再加个注解让使用更加简便。
1.创建注解@RedissonLock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface RedissonLock {
String prefixKey() default "";
String key();
int waitTime() default -1;
TimeUnit unit() default TimeUnit.MILLISECONDS;
}
|
2.实现切面RedissonLockAspect
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Slf4j @Aspect @Component @Order(0) public class RedissonLockAspect { @Autowired private LockService lockService;
@Around("@annotation(com.abin.mallchat.common.common.annotation.RedissonLock)") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); RedissonLock redissonLock = method.getAnnotation(RedissonLock.class); String prefix = StrUtil.isBlank(redissonLock.prefixKey()) ? SpElUtils.getMethodKey(method) : redissonLock.prefixKey(); String key = SpElUtils.parseSpEl(method, joinPoint.getArgs(), redissonLock.key()); return lockService.executeWithLockThrows(prefix + ":" + key, redissonLock.waitTime(), redissonLock.unit(), joinPoint::proceed); } }
|