Vite 从入门到精通,玩转新时代前端构建法则
/**
* 锁战略笼统基类
*/
@Slf4j
abstract class LockStrategy {
@Autowired
private RedissonClient redissonClient;
/**
* 创立RLock
*
* @param keys
* @param parameterNames
* @param args
* @param keyConstant
* @return
*/
abstract RLock createLock(String[] keys, String[] parameterNames, Object[] args, String keyConstant, RedissonClient redissonClient);
/**
* 获取RLock
*
* @param keys
* @param parameterNames
* @param args
* @param keyConstant
* @return
*/
public RLock[] getRLocks(String[] keys, String[] parameterNames, Object[] args, String keyConstant) {
List rLocks = new ArrayList<>();
for (String key : keys) {
List valueBySpel = getValueBySpel(key, parameterNames, args, keyConstant);
for (String s : valueBySpel) {
rLocks.add(redissonClient.getLock(s));
}
}
RLock[] locks = new RLock[rLocks.size()];
int index = 0;
for (RLock r : rLocks) {
locks[index++] = r;
}
return locks;
}
/**
* 经过spring Spel 获取参数
*
* @param key 定义的key值 以#开头 例如:#user
* @param parameterNames 形参
* @param args 形参值
* @param keyConstant key的常亮
* @return
*/
List getValueBySpel(String key, String[] parameterNames, Object[] args, String keyConstant) {
List keys = new ArrayList<>();
if (!key.contains(PLACE_HOLDER)) {
String s = REDISSON_LOCK + key + keyConstant;
log.info("没有运用spel表达式value->{}", s);
keys.add(s);
return keys;
}
// spel解析器
ExpressionParser parser = new SpelExpressionParser();
// spel上下文
EvaluationContext context = new StandardEvaluationContext();
for (int i = 0; i < parameterNames.length; i++) {
context.setVariable(parameterNames[i], args[i]);
}
Expression expression = parser.parseExpression(key);
Object value = expression.getValue(context);
if (value != null) {
if (value instanceof List) {
List valueList = (List) value;
for (Object o : valueList) {
keys.add(REDISSON_LOCK + o.toString() + keyConstant);
}
} else if (value.getClass().isArray()) {
Object[] objects = (Object[]) value;
for (Object o : objects) {
keys.add(REDISSON_LOCK + o.toString() + keyConstant);
}
} else {
keys.add(REDISSON_LOCK + value.toString() + keyConstant);
}
}
log.info("spel表达式key={},value={}", key, keys);
return keys;
}
}
复制代码
再提供各种锁形式的详细完成:
-
可重入锁:
/**
- 可重入锁战略 */ public class ReentrantLockStrategy extends LockStrategy { @Override public RLock createLock(String[] keys, String[] parameterNames, Object[] args, String keyConstant, RedissonClient redissonClient) { List valueBySpel = getValueBySpel(keys[0], parameterNames, args, keyConstant); //假如spel表达式是数组或者汇合 则运用红锁 if (valueBySpel.size() == 1) { return redissonClient.getLock(valueBySpel.get(0)); } else { RLock[] locks = new RLock[valueBySpel.size()]; int index = 0; for (String s : valueBySpel) { locks[index++] = redissonClient.getLock(s); } return new RedissonRedLock(locks); } } } 复制代码
-
公平锁:download
/**
- 公平锁战略 */ public class FairLockStrategy extends LockStrategy { @Override public RLock createLock(String[] keys, String[] parameterNames, Object[] args, String keyConstant, RedissonClient redissonClient) { return redissonClient.getFairLock(getValueBySpel(keys[0], parameterNames, args, keyConstant).get(0)); } } 复制代码
-
联锁
/**
- 联锁战略 */ public class MultipleLockStrategy extends LockStrategy { @Override public RLock createLock(String[] keys, String[] parameterNames, Object[] args, String keyConstant, RedissonClient redissonClient) { RLock[] locks = getRLocks(keys, parameterNames, args, keyConstant); return new RedissonMultiLock(locks); } } 复制代码
-
红锁
/**
- 红锁战略 */ public class RedLockStrategy extends LockStrategy { @Override public RLock createLock(String[] keys, String[] parameterNames, Object[] args, String keyConstant, RedissonClient redissonClient) { RLock[] locks = getRLocks(keys, parameterNames, args, keyConstant); return new RedissonRedLock(locks); } } 复制代码
-
读锁
/**
- 读锁战略 */ public class ReadLockStrategy extends LockStrategy { @Override public RLock createLock(String[] keys, String[] parameterNames, Object[] args, String keyConstant, RedissonClient redissonClient) { RReadWriteLock rwLock = redissonClient.getReadWriteLock(getValueBySpel(keys[0], parameterNames, args, keyConstant).get(0)); return rwLock.readLock(); } } 复制代码
-
写锁
/**
- 写锁战略 */ public class WriteLockStrategy extends LockStrategy { @Override public RLock createLock(String[] keys, String[] parameterNames, Object[] args, String keyConstant, RedissonClient redissonClient) { RReadWriteLock rwLock = redissonClient.getReadWriteLock(getValueBySpel(keys[0], parameterNames, args, keyConstant).get(0)); return rwLock.writeLock(); } } 复制代码
最后提供一个战略工厂初始化锁战略:
/**
* 锁的战略工厂
*/
@Service
public class LockStrategyFactory {
private LockStrategyFactory() {
}
private static final Map<LockModel, LockStrategy> STRATEGIES = new HashMap<>(6);
static {
STRATEGIES.put(LockModel.FAIR, new FairLockStrategy());
STRATEGIES.put(LockModel.REENTRANT, new ReentrantLockStrategy());
STRATEGIES.put(LockModel.RED_LOCK, new RedLockStrategy());
STRATEGIES.put(LockModel.READ, new ReadLockStrategy());
STRATEGIES.put(LockModel.WRITE, new WriteLockStrategy());
STRATEGIES.put(LockModel.MULTIPLE, new MultipleLockStrategy());
}
public RLock createLock(LockModel lockModel, String[] keys, String[] parameterNames, Object[] args, String keyConstant, RedissonClient redissonClient) {
return STRATEGIES.get(lockModel).createLock(keys, parameterNames, args, keyConstant, redissonClient);
}
}
复制代码
8、运用方式
@Lock(keys = "#query.channel") // 支持spel
@ApiOperation("分页列表")
@GetMapping
public ApiPageResult list(VendorProjectItemQuery query, Pagination pagination) {
return ApiPageResult.success(pagination, vendorProjectItemService.list(query, pagination), vendorProjectItemService.count(query));
}