对于最新的稳定版本,请使用 Spring Integration 6.5.1! |
索赔检查
在前面的部分中,我们介绍了几个内容丰富组件,它们可以帮助您处理消息缺少一段数据的情况。 我们还讨论了内容过滤,它允许您从消息中删除数据项。 但是,有时我们想暂时隐藏数据。 例如,在分布式系统中,我们可能会收到一条有效负载非常大的消息。 某些间歇性消息处理步骤可能不需要访问此有效负载,而某些步骤可能只需要访问某些标头,因此通过每个处理步骤携带大型消息有效负载可能会导致性能下降,可能产生安全风险,并可能使调试更加困难。
存储在库中(或声明检查)模式描述了一种机制,该机制允许您将数据存储在已知位置,同时仅维护指向该数据所在位置的指针(声明检查)。 您可以将该指针作为新消息的有效负载传递,从而让消息流中的任何组件在需要时立即获取实际数据。 这种方法与挂号信流程非常相似,您在邮箱中收到索赔支票,然后必须去邮局领取您的实际包裹。 这也与飞行后或酒店的行李领取理念相同。
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 是该消息的声明检查。声明检查还成为发送到output-channel
.
现在,假设在某个时候您确实需要访问实际消息。您可以手动访问消息存储并获取消息的内容,也可以使用相同的方法(创建转换器),只是现在您使用传出声明检查转换器将声明检查转换为实际消息。
以下列表概述了传入声明检查转换器的所有可用参数:
<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 .
自选。 |
5 | 指定此终结点作为通道的订阅者连接到时的调用顺序。当该通道使用failover dispatching 策略。当此端点本身是具有队列的通道的轮询使用者时,它不起作用。此属性在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
应将声明检查作为其有效负载。传出声明检查转换器通过查询消息存储中提供的声明检查标识的消息,将其转换为具有原始有效负载的消息。然后,它将新签出的消息发送到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 .
自选。 |
5 | 指定此端点作为通道的订阅者连接到时的调用顺序。当该通道使用failover dispatching 策略。当此端点本身是具有队列的通道的轮询使用者时,它不起作用。此属性在Chain 元素。 自选。 |
6 | 标识消息在此端点处理后发送的消息通道。此属性在Chain 元素。 自选。 |
7 | 如果设置为true ,则该消息将从MessageStore 通过这个转换器。当 Message 只能“声明”一次时,此设置很有用。它默认为false .
自选。 |
8 | 指定向输出通道发送回复消息时等待的最长时间(以毫秒为单位)。它默认为30 秒。 此属性在Chain 元素。 自选。 |
9 | 定义轮询器。此元素在Chain 元素。 自选。 |
领取一次
有时,特定消息只能领取一次。以此类推,考虑处理飞机行李的流程。您在出发时托运行李,并在抵达时领取行李。行李一旦被认领,如果不先重新托运,就无法再次领取行李。为了适应这种情况,我们引入了remove-message
boolean 属性claim-check-out
转换器。 此属性设置为false
默认情况下。但是,如果设置为true
,则已声明的邮件将从MessageStore
这样就不能再次认领了。
此功能对存储空间有影响,尤其是在内存中Map
-基于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
-based 实现(默认,适合测试) -
JdbcMessageStore
:通过 JDBC 使用关系数据库的实现