如果入站连接工厂是TcpNetServerConnectionFactory,您可以简单地使用ThreadAffinityClientConnectionFactory,因为每个入站连接都有自己的线程。
您可以致电getConnection()。这会将连接绑定到线程(并且您可以从中获取连接 id),但是由于线程关联,您实际上并不需要在这个方向上映射标头,您只需要在返回路径上进行映射.
但请记住,如果ThreadAffinityClientConnectionFactory 检测到连接已关闭,它将创建一个新连接。因此,您可能希望在每次调用时在映射器中调用 getConnection()。但是,仍然存在竞争条件,因此您可能还需要监听 TcpConnectionCloseEvents 和 TcpConnectionOpenEvents。
如果您在入站上使用 NIO,或者通过执行程序将工作交给其他线程,这将不起作用。
在这种情况下,您需要自己的包装连接工厂 - 您可以使用 ThreadAffinityClientConnectionFactory 作为模型,但不是将连接存储在 ThreadLocal 中,而是将它们存储在地图中。但是你仍然需要一个ThreadLocal(在每次调用时设置上游)来告诉工厂当适配器要求一个连接时分发哪个连接。
但是,您需要注意一个技巧。
连接工厂上有一个属性singleUse。这有两个目的;
- 首先,它告诉工厂每次调用
getConnection() 时创建一个新连接,而不是单个共享连接
- 第二,它告诉入站适配器在收到回复后关闭连接
所以诀窍是您需要在真实工厂上使用singleUse=true(因此每次调用getConnection() 时都会为您提供一个新连接),但在包装工厂上需要singleUse=false,因此适配器不会关闭连接.
我建议您查看ThreadAffinityClientConnectionFactory 和CachingClientConnectionFactory 连接工厂,看看它们是如何工作的。
我们可能应该考虑将其拆分为两个布尔值;我们可能还可以通过在客户端工厂合同中添加getConnection(String connectionId) 之类的内容并让工厂在内部查找连接来进行一些改进以避免对本地线程的需要;但这需要在适配器中工作。
我将为此捕获一个问题,看看我们是否可以在 5.2 中得到一些东西。
相当长的答案,但我希望它有意义。