Spring Integration Message<Payload> vs Payload 作为输出参数

Spring Integration Message<Payload> vs Payload as output parameter

我有一个 spring 集成流程,其中包含 jdbc 出站网关和 select query SELECT * FROM Users WHERE userId=:payload 最初我的网关方法就像

public List<UserBO> findUser(String userId);

我有行映射器,可将数据从 sql 结果映射到 UserBO object。 在上述情况下,即使 sql 结果集中有 1 行或多行,我也总是得到一个用户列表。

我已将网关方法更改为

public Message<List<UserBO>> findUser(String userId);

因为我需要消息中的 header 值。 现在的问题是,当 sql 结果集中有 2 行或更多行时,我在返回消息中的有效负载是用户 object 的列表。但是,如果 sql 结果集中只有一行,则有效负载是一个 UserBO object;不是 userBO objects.

的列表

所以我需要在处理响应消息之前检查负载实例。 这是 Spring 集成的预期行为吗?

啊!我懂了。问题出在 ConversionService.

附近

Spring 集成中的所有组件接受 Message<?> 和 returns Message<?> 独立于您的参数提取。

这是第一个事实。

第二个:JdbcOutboundGateway有代码:

if (list.size() == 1) {
    payload = list.get(0);
}
return this.getMessageBuilderFactory().withPayload(payload).copyHeaders(requestMessage.getHeaders()).build();

如您所见,returns Message<?> 正如我们之前所说,但请注意它有哪些 payload

链中的下一个事实。

您网关的方法有签名:

public Message<List<UserBO>> findUser(String userId);

所以,return一个Message<?>!由于我们已经从 JdbcOutboundGateway 回复中获得消息,因此无需关心 payload 转换 。瞧!你想得到 Message<List<UserBO>>,但它只是 Message<UserBO>,因为 JdbcOutboundGateway 逻辑。

由于泛型是一个编译时特性,我们可以简单地将最后一个转换为第一个,但是当我们尝试从中提取并转换 payload 时,我们会得到 ClassCastException

第一种情况效果很好,因为我们从回复消息中提取了您的单个 UserBO payload 并将其发送到 ConversionService 以转换为 List<UserBO> 作为您的第一个变体需要。

在这种情况下,它可以简单地为我们实例化一个 Collection 并在那里填充我们的单个对象。

Message<T> 案例无事可做。因为我们无法从那里提取通用类型。或者更好的是我们不想那样做。因为正是这种与 Message 对象的通信使我们能够绕过 ConversionService 并获得更好的性能和吞吐量。

希望我清楚。