锁建议
从 6.5 版本开始,引入了 LockRequestHandlerAdvice
。
此建议针对请求消息评估锁键,并执行 LockRegistry.executeLocked()
API。
此建议的目标是根据 lockKey
上下文实现对服务调用的独占访问,这意味着不同的键仍然可以并发访问服务。
LockRequestHandlerAdvice
需要一个 LockRegistry 和一个静态、SpEL 或基于函数的锁键回调。
如果 lockKey
被评估为 null
,则在服务调用周围不持有任何锁。
但是,可以提供一个 discardChannel
——具有 null 键的消息将被发送到此通道。
此外,还可以提供 waitLockDuration
选项,以使用 Lock.tryLock(long, TimeUnit)
API 而不是 Lock.lockInterruptibly()
。
以下是 LockRequestHandlerAdvice
的使用示例:
@Bean
LockRegistry lockRegistry() {
return new DefaultLockRegistry();
}
@Bean
QueueChannel discardChannel() {
return new QueueChannel();
}
@Bean
LockRequestHandlerAdvice lockRequestHandlerAdvice(LockRegistry lockRegistry, QueueChannel discardChannel) {
LockRequestHandlerAdvice lockRequestHandlerAdvice =
new LockRequestHandlerAdvice(lockRegistry, (message) -> message.getHeaders().get(LOCK_KEY_HEADER));
lockRequestHandlerAdvice.setDiscardChannel(discardChannel);
lockRequestHandlerAdvice.setWaitLockDurationExpressionString("'PT1s'");
return lockRequestHandlerAdvice;
}
AtomicInteger counter = new AtomicInteger();
@ServiceActivator(inputChannel = "inputChannel", adviceChain = "lockRequestHandlerAdvice")
String handleWithDelay(String payload) throws InterruptedException {
int currentCount = this.counter.incrementAndGet();
Thread.sleep("longer_process".equals(payload) ? 2000 : 500);
try {
return payload + "-" + currentCount;
}
finally {
this.counter.decrementAndGet();
}
}