注解方式优雅的实现 Redisson 分布式锁
阅读本文大概需要 4 分钟。
来自:juejin.cn/post/7215142807861379109
1前言
2Redisson分布式锁常规使用
Lock
public void getLock(){
//获取锁
RLock lock = redisson.getLock("Lxlxxx_Lock");
try {
// 2.加锁
lock.lock();
} catch (InterruptedException e) {
e.getStackTrace();
} finally {
// 3.解锁
lock.unlock();
System.out.println("Finally,释放锁成功");
}
TryLock
RLock lock = redisson.getLock(name);
try {
if (lock.tryLock(2, 10, TimeUnit.SECONDS)) {
//执行业务逻辑
} else {
System.out.println("已存在");
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//判断当前线程持有的锁是不是处于锁定状态,锁定状态再进行释放
if (this.redissonLock.isHeldByCurrentThread(lockName)) {
this.redissonLock.unlock(lockName);
}
}
3自定义注解实现锁机制
自定义注解
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface DistributedLock {
String key() default "";
int leaseTime() default 10;
boolean autoRelease() default true;
String errorDesc() default "系统正常处理,请稍后提交";
int waitTime() default 1;
}
切面类实现
@Aspect
@Component
public class DistributedLockHandler {
private static final Logger log = LoggerFactory.getLogger(DistributedLockHandler.class);
@Autowired
RedissonLock redissonLock;
public DistributedLockHandler() {
}
@Around("@annotation(distributedLock)")
public Object around(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) throws Throwable {
String lockName = this.getRedisKey(joinPoint, distributedLock);
int leaseTime = distributedLock.leaseTime();
String errorDesc = distributedLock.errorDesc();
int waitTime = distributedLock.waitTime();
Object var8;
try {
boolean lock = this.redissonLock.tryLock(lockName, (long)leaseTime, (long)waitTime);
if (!lock) {
throw new RuntimeException(errorDesc);
}
var8 = joinPoint.proceed();
} catch (Throwable var12) {
log.error("执行业务方法异常", var12);
throw var12;
} finally {
if (this.redissonLock.isHeldByCurrentThread(lockName)) {
this.redissonLock.unlock(lockName);
}
}
return var8;
}
/**
* 获取加锁的key
* @param joinPoint
* @param distributedLock
* @return
*/
private String getRedisKey(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) {
String key = distributedLock.key();
Object[] parameterValues = joinPoint.getArgs();
MethodSignature signature = (MethodSignature)joinPoint.getSignature();
Method method = signature.getMethod();
DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
String[] parameterNames = nameDiscoverer.getParameterNames(method);
if (StringUtils.isEmpty(key)) {
if (parameterNames != null && parameterNames.length > 0) {
StringBuffer sb = new StringBuffer();
int i = 0;
for(int len = parameterNames.length; i < len; ++i) {
sb.append(parameterNames[i]).append(" = ").append(parameterValues[i]);
}
key = sb.toString();
} else {
key = "redissionLock";
}
return key;
} else {
SpelExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(key);
if (parameterNames != null && parameterNames.length != 0) {
EvaluationContext evaluationContext = new StandardEvaluationContext();
for(int i = 0; i < parameterNames.length; ++i) {
evaluationContext.setVariable(parameterNames[i], parameterValues[i]);
}
try {
Object expressionValue = expression.getValue(evaluationContext);
return expressionValue != null && !"".equals(expressionValue.toString()) ? expressionValue.toString() : key;
} catch (Exception var13) {
return key;
}
} else {
return key;
}
}
}
}
具体使用
4总结
推荐阅读:
面试官:如何使用 Dockerfile 去构建自定义的 Docker 镜像?问倒一大片.....
互联网初中高级大厂面试题(9个G) 内容包含Java基础、JavaWeb、MySQL性能优化、JVM、锁、百万并发、消息队列、高性能缓存、反射、Spring全家桶原理、微服务、Zookeeper......等技术栈!
⬇戳阅读原文领取! 朕已阅