锁建议
从版本 6.5 开始,引入了 LockRequestHandlerAdvice。此建议针对请求消息评估一个锁键,并执行 LockRegistry.executeLocked() API。该建议的目标是根据 lockKey 上下文实现对服务调用的独占访问,这意味着不同的键仍然可以并发访问服务。
LockRequestHandlerAdvice 需要一个 LockRegistry,以及一个静态的、基于 SpEL 或基于函数的锁键回调。如果 lockKey 评估为 null,则服务调用周围不会持有锁。但是,可以提供一个 discardChannel——具有空键的消息将发送到此通道。此外,可以提供一个 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();
}
}