Context Holder Advice
Starting with version 6.1, the ContextHolderRequestHandlerAdvice
has been introduced.
This advice takes some value from the request message as and stores it in the context holder.
The value is clear from the context when an execution is finished on the target MessageHandler
.
The best way to think about this advice is similar to the programming flow where we store some value into a ThreadLocal
, get access to it from the target call and then clean up the ThreadLocal
after execution.
The ContextHolderRequestHandlerAdvice
requires these constructor arguments: a Function<Message<?>, Object>
as a value provider, Consumer<Object>
as a context set callback and Runnable
as a context clean up hook.
Following is a sample how a ContextHolderRequestHandlerAdvice
can be used in combination with a 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");
}
And it is just enough to send a message to the in
channel with a FACTORY_KEY
header set to either one
or two
.
The ContextHolderRequestHandlerAdvice
sets the value from that header into a DelegatingSessionFactory
via its setThreadKey
.
Then when FtpOutboundGateway
executes an ls
command a proper delegating SessionFactory
is chosen from the DelegatingSessionFactory
according to the value in its ThreadLocal
.
When the result is produced from the FtpOutboundGateway
, a ThreadLocal
value in the DelegatingSessionFactory
is cleared according to the clearThreadKey()
call from the ContextHolderRequestHandlerAdvice
.
See Delegating Session Factory for more information.