Context Holder 建議

從 6.1 版本開始,引入了 ContextHolderRequestHandlerAdvice。此建議從請求訊息中取得某些值,並將其儲存在 context holder 中。當目標 MessageHandler 上的執行完成時,context 中的值會被清除。思考此建議的最佳方式,是類似於將某些值儲存到 ThreadLocal 的程式設計流程,從目標呼叫中存取它,然後在執行後清除 ThreadLocalContextHolderRequestHandlerAdvice 需要以下建構子引數:一個 Function<Message<?>, Object> 作為值提供者,Consumer<Object> 作為 context 設定回呼,以及 Runnable 作為 context 清理 hook。

以下範例說明如何將 ContextHolderRequestHandlerAdviceo.s.i.file.remote.session.DelegatingSessionFactory 結合使用

@Bean
DelegatingSessionFactory<?> dsf(SessionFactory<?> one, SessionFactory<?> two) {
    return new DelegatingSessionFactory<>(Map.of("one", one, "two", two), null);
}

@Bean
ContextHolderRequestHandlerAdvice contextHolderRequestHandlerAdvice(DelegatingSessionFactory<String> dsf) {
    return new ContextHolderRequestHandlerAdvice(message -> message.getHeaders().get("FACTORY_KEY"),
                                      dsf::setThreadKey, dsf::clearThreadKey);
}

@ServiceActivator(inputChannel = "in", adviceChain = "contextHolderRequestHandlerAdvice")
FtpOutboundGateway ftpOutboundGateway(DelegatingSessionFactory<?> sessionFactory) {
	return new FtpOutboundGateway(sessionFactory, "ls", "payload");
}

只需將訊息傳送到 in 通道,並將 FACTORY_KEY 標頭設定為 onetwo 即可。ContextHolderRequestHandlerAdvice 透過其 setThreadKey 將該標頭中的值設定到 DelegatingSessionFactory 中。然後,當 FtpOutboundGateway 執行 ls 命令時,會根據 DelegatingSessionFactoryThreadLocal 的值,從 DelegatingSessionFactory 中選擇適當的委派 SessionFactory。當從 FtpOutboundGateway 產生結果時,會根據 ContextHolderRequestHandlerAdvice 中的 clearThreadKey() 呼叫,清除 DelegatingSessionFactory 中的 ThreadLocal 值。請參閱 委派 Session Factory 以取得更多資訊。