Context Holder Advice

从 6.1 版本开始,引入了 ContextHolderRequestHandlerAdvice。此建议从请求消息中获取一些值,并将其存储在上下文持有者中。当目标 MessageHandler 上的执行完成时,值会从上下文中清除。考虑此建议的最好方法类似于编程流程,我们在其中将一些值存储到 ThreadLocal 中,从目标调用中获取它,然后在执行后清理 ThreadLocalContextHolderRequestHandlerAdvice 需要这些构造函数参数:一个 Function<Message<?>, Object> 作为值提供者、Consumer<Object> 作为上下文设置回调和 Runnable 作为上下文清理钩子。

以下是 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 通道就足够了,该消息带有设置为 onetwoFACTORY_KEY 标头。ContextHolderRequestHandlerAdvice 通过其 setThreadKey 将该标头中的值设置到 DelegatingSessionFactory 中。然后,当 FtpOutboundGateway 执行 ls 命令时,会从 DelegatingSessionFactory 中根据其 ThreadLocal 中的值选择适当的委托 SessionFactory 。当从 FtpOutboundGateway 产生结果时,会根据 ContextHolderRequestHandlerAdvice 中的 clearThreadKey() 调用清除 DelegatingSessionFactory 中的 ThreadLocal 值。有关更多信息,请参阅 Delegating Session Factory