上下文持有者 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通道发送一条消息,并设置FACTORY_KEY头为onetwo即可。ContextHolderRequestHandlerAdvice将该头部的值通过setThreadKey方法设置到DelegatingSessionFactory中。然后,当FtpOutboundGateway执行ls命令时,会根据ThreadLocal中的值从DelegatingSessionFactory中选择一个合适的委托SessionFactory。当FtpOutboundGateway产生结果时,DelegatingSessionFactory中的ThreadLocal值会根据ContextHolderRequestHandlerAdvice中的clearThreadKey()调用被清除。有关更多信息,请参见委托会话工厂