コンテキストホルダーのアドバイス

バージョン 6.1 から、ContextHolderRequestHandlerAdvice が導入されました。このアドバイスは、リクエストメッセージから値を取得し、それをコンテキストホルダーに保存します。ターゲット MessageHandler で実行が終了すると、値はコンテキストから明らかになります。このアドバイスについて考える最良の方法は、何らかの値を ThreadLocal に格納し、ターゲット呼び出しからその値にアクセスし、実行後に ThreadLocal をクリーンアップするプログラミングフローに似ています。ContextHolderRequestHandlerAdvice には、値プロバイダーとしての Function<Message<?>, Object>、コンテキストセットコールバックとしての Consumer<Object>、およびコンテキストクリーンアップフックとしての Runnable というコンストラクター引数が必要です。

以下は、ContextHolderRequestHandlerAdvice を o.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");
}

また、FACTORY_KEY ヘッダーを one または two に設定して、メッセージを in チャネルに送信するだけで十分です。ContextHolderRequestHandlerAdvice は、そのヘッダーの値を setThreadKey を介して DelegatingSessionFactory に設定します。次に、FtpOutboundGateway が ls コマンドを実行すると、ThreadLocal の値に従って、適切な委譲 SessionFactory が DelegatingSessionFactory から選択されます。FtpOutboundGateway から結果が生成されると、ContextHolderRequestHandlerAdvice からの clearThreadKey() 呼び出しに従って、DelegatingSessionFactory 内の ThreadLocal 値がクリアされます。詳細については、"セッションファクトリの委譲" を参照してください。