锁建议

从 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();
    }
}