赞
踩
lock.lock(leaseTime, timeUnit);
return callback.process();
} finally {
if (lock != null && lock.isLocked()) {
lock.unlock();
}
}
}
@Override
public T tryLock(DistributedLockCallback callback, boolean fairLock) {
return tryLock(callback, DEFAULT_WAIT_TIME, DEFAULT_TIMEOUT, DEFAULT_TIME_UNIT, fairLock);
}
@Override
public T tryLock(DistributedLockCallback callback, long waitTime, long leaseTime, TimeUnit timeUnit, boolean fairLock) {
RLock lock = getLock(callback.getLockName(), fairLock);
try {
if (lock.tryLock(waitTime, leaseTime, timeUnit)) {
return callback.process();
}
} catch (InterruptedException e) {
} finally {
if (lock != null && lock.isLocked()) {
lock.unlock();
}
}
return null;
}
private RLock getLock(String lockName, boolean fairLock) {
RLock lock;
if (fairLock) {
lock = redisson.getFairLock(lockName);
} else {
lock = redisson.getLock(lockName);
}
return lock;
}
public void setRedisson(RedissonClient redisson) {
this.redisson = redisson;
}
}
使用SingleDistributedLockTemplate
DistributedLockTemplate lockTemplate = …;
final String lockName = …;
lockTemplate.lock(new DistributedLockCallback() {
@Override
public Object process() {
//do some business
return null;
}
@Override
public String getLockName() {
return lockName;
}
}, false);
但是每次使用分布式锁都要写类似上面的重复代码,有没有什么方法可以只关注核心业务逻辑代码的编写,即上面的"do some business"。下面介绍如何使用Spring AOP来实现这一目标。
定义注解@DistributedLock
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DistributedLock {
/**
锁的名称。
如果lockName可以确定,直接设置该属性。
*/
String lockName() default “”;
/**
*/
String lockNamePre() default “”;
/**
*/
String lockNamePost() default “lock”;
/**
获得锁名时拼接前后缀用到的分隔符
@return
*/
String separator() default “.”;
/**
获取注解的方法参数列表的某个参数对象的某个属性值来作为lockName。因为有时候lockName是不固定的。
当param不为空时,可以通过argNum参数来设置具体是参数列表的第几个参数,不设置则默认取第一个。
*/
String param() default “”;
/**
*/
int argNum() default 0;
/**
是否使用公平锁。
公平锁即先来先得。
*/
boolean fairLock() default false;
/**
*/
boolean tryLock() default false;
/**
最长等待时间。
该字段只有当tryLock()返回true才有效。
*/
long waitTime() default 30L;
/**
锁超时时间。
超时时间过后,锁自动释放。
建议:
尽量缩简需要加锁的逻辑。
*/
long leaseTime() default 5L;
/**
*/
TimeUnit timeUnit() default TimeUnit.SECONDS;
}
定义切面代码
@Aspect
@Component
public class DistributedLockAspect {
@Autowired
private DistributedLockTemplate lockTemplate;
@Pointcut(“@annotation(cn.sprinkle.study.distribute
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。