鎖建議
從版本 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();
}
}