|
如需使用最新稳定版本,请使用 Spring Integration 7.0.4! |
索赔检查
在之前的章节中,我们介绍了几种内容增强器组件,它们可以帮助您处理消息缺少部分数据的情况。 我们还讨论了内容过滤,它允许您从消息中移除数据项。 然而,有时我们需要暂时隐藏数据。 例如,在分布式系统中,我们可能会收到一个负载非常大的消息。 某些间歇性的消息处理步骤可能不需要访问此负载,而另一些步骤可能只需要访问某些标头,因此在每个处理步骤中传递大型消息负载可能会导致性能下降、产生安全风险,并增加调试难度。
库中的存储(或称凭单)模式描述了一种机制,允许您将数据存储在一个已知的位置,同时仅保留指向该数据位置的指针(即凭单)。 您可以将该指针作为新消息的有效载荷进行传递,从而使消息流中的任意组件在需要时能够立即获取实际数据。 这种方法与挂号信流程非常相似:您会在信箱中收到一个取件凭单,然后必须前往邮局领取您的实际包裹。 这与飞行后或酒店中的行李提取处的理念也是相同的。
Spring Integration 提供两种类型的凭据检查转换器:
-
传入索赔检查转换器
-
出站索赔检查转换器
提供了基于命名空间的便捷机制来配置它们。
传入索赔检查转换器
传入的凭证检查转换器通过将消息存储在其message-store属性标识的消息存储中,来转换传入的消息。
以下示例定义了一个传入的凭证检查转换器:
<int:claim-check-in id="checkin"
input-channel="checkinChannel"
message-store="testMessageStore"
output-channel="output"/>
在前述配置中,在 input-channel 上接收的消息会被持久化到由 message-store 属性标识的消息存储中,并使用生成的 ID 进行索引。
该 ID 即为该消息的凭证(claim check)。
该凭证同时成为发送到 output-channel 的新(转换后)消息的有效载荷。
现在,假设在某个时刻您确实需要访问实际的消息内容。 您可以手动访问消息存储并获取消息内容,或者使用相同的方法(创建转换器),但此时您通过使用出站Claim Check转换器将Claim Check转换为实际消息。
以下列表提供了传入索赔检查转换器的所有可用参数概述:
<int:claim-check-in auto-startup="true" (1)
id="" (2)
input-channel="" (3)
message-store="messageStore" (4)
order="" (5)
output-channel="" (6)
send-timeout=""> (7)
<int:poller></int:poller> (8)
</int:claim-check-in>
| 1 | 生命周期属性,指示该组件是否应在应用程序上下文启动期间启动。
其默认值为 true。
此属性在 Chain 元素内不可用。
可选。 |
| 2 | 标识底层 bean 定义的 ID(MessageTransformingHandler)。
此属性在 Chain 元素内部不可用。
可选。 |
| 3 | 此端点的接收消息通道。
此属性在 Chain 元素内部不可用。
可选。 |
| 4 | 引用由该索赔检查转换器使用的 MessageStore。
如果未指定,默认引用为名为 messageStore 的 Bean。
可选。 |
| 5 | 指定当此端点作为订阅者连接到通道时的调用顺序。
当该通道使用 failover 分发策略时,这一点尤为重要。
如果此端点本身是带有队列的通道的轮询消费者,则此属性无效。
此属性在 Chain 元素内部不可用。
可选。 |
| 6 | 标识经过此端点处理后发送消息的消息通道。
此属性在 Chain 元素内部不可用。
可选。 |
| 7 | 指定向输出通道发送回复消息时等待的最长时间(以毫秒为单位)。
默认为 30 秒。
此属性在 Chain 元素内不可用。
可选。 |
| 8 | 定义一个轮询器。
此元素不可在 Chain 元素内部使用。
可选。 |
出站索赔检查转换器
出站声明检查转换器允许您将带有声明检查负载的消息转换为以原始内容作为负载的消息。
<int:claim-check-out id="checkout"
input-channel="checkoutChannel"
message-store="testMessageStore"
output-channel="output"/>
在上述配置中,在 input-channel 上接收到的消息应将其负载作为索赔检查(claim check)。
出站索赔检查转换器通过查询消息存储中由提供的索赔检查标识的消息,将其转换为具有原始负载的消息。
然后,它将新提取的消息发送到 output-channel。
以下列表提供了出站索赔检查转换器的所有可用参数概述:
<int:claim-check-out auto-startup="true" (1)
id="" (2)
input-channel="" (3)
message-store="messageStore" (4)
order="" (5)
output-channel="" (6)
remove-message="false" (7)
send-timeout=""> (8)
<int:poller></int:poller> (9)
</int:claim-check-out>
| 1 | 生命周期属性,指示该组件是否应在应用程序上下文启动期间启动。
其默认值为 true。
此属性在 Chain 元素内不可用。
可选。 |
| 2 | 标识底层 bean 定义的 ID(MessageTransformingHandler)。
此属性在 Chain 元素内部不可用。
可选。 |
| 3 | 此端点的接收消息通道。
此属性在 Chain 元素内部不可用。
可选。 |
| 4 | 引用由该索赔检查转换器使用的 MessageStore。
如果未指定,默认引用为名为 messageStore 的 Bean。
可选。 |
| 5 | 指定当此端点作为订阅者连接到通道时的调用顺序。
当该通道使用 failover 分发策略时,这一点尤为重要。
如果此端点本身是带有队列的通道的轮询消费者,则此属性无效。
此属性在 Chain 元素内部不可用。
可选。 |
| 6 | 标识经过此端点处理后发送消息的消息通道。
此属性在 Chain 元素内部不可用。
可选。 |
| 7 | 如果设置为 true,此转换器将从 MessageStore 中移除该消息。
当消息只能被“认领”一次时,此设置非常有用。
默认值为 false。
可选。 |
| 8 | 指定向输出通道发送回复消息时等待的最长时间(以毫秒为单位)。
默认为 30 秒。
此属性在 Chain 元素内不可用。
可选。 |
| 9 | 定义一个轮询器。
此元素不可在 Chain 元素内部使用。
可选。 |
领取一次
有时,特定的消息必须只能被认领一次。
作为一个类比,可以考虑处理飞机行李的过程。
您在出发时办理行李托运,在到达时领取行李。
一旦行李被领取,如果不先重新办理托运,就不能再次领取。
为了适应此类情况,我们在 remove-message 转换器上引入了一个布尔属性 claim-check-out。
该属性的默认值为 false。
然而,如果将其设置为 true,已认领的消息将从 MessageStore 中移除,以便无法再次被认领。
此功能会影响存储空间,尤其是在基于内存的 Map-based SimpleMessageStore 的情况下,如果未能删除消息,最终可能导致 OutOfMemoryException。
因此,如果您不期望有多个声明,我们建议将 remove-message 属性的值设置为 true。
以下示例展示了如何使用 remove-message 属性:
<int:claim-check-out id="checkout"
input-channel="checkoutChannel"
message-store="testMessageStore"
output-channel="output"
remove-message="true"/>
关于消息存储的说明
虽然我们很少关心索赔检查的细节(只要它们能正常工作),但您应该知道,Spring Integration 中实际索赔检查(即指针)的当前实现使用 UUID 来确保唯一性。
org.springframework.integration.store.MessageStore 是一个用于存储和检索消息的策略接口。
Spring Integration 提供了两种方便的实现:
-
SimpleMessageStore: 一种基于内存的、Map的实现(默认选项,适用于测试) -
JdbcMessageStore: 一个使用 JDBC 通过关系型数据库实现的实现