元数据存储
许多外部系统、服务或资源是非事务性的(例如 Twitter、RSS、文件系统等),并且无法将数据标记为已读取。此外,有时您可能需要在某些集成解决方案中实现企业集成模式 幂等接收器。为了实现此目标并存储与外部系统下一次交互之前端点的某些先前状态或处理下一条消息,Spring 集成提供元数据存储组件作为 `org.springframework.integration.metadata.MetadataStore` 接口的实现,具有通用的键值契约。
元数据存储旨在存储各种类型的通用元数据(例如,已处理的最后一个 Feed 条目的发布日期),以帮助诸如 Feed 适配器之类的组件处理重复项。如果组件没有直接提供对 `MetadataStore` 的引用,则查找元数据存储的算法如下:首先,在应用程序上下文中查找具有 `metadataStore` ID 的 Bean。如果找到,则使用它。否则,创建一个新的 `SimpleMetadataStore` 实例,这是一个内存实现,仅在当前运行的应用程序上下文的生命周期内持久化元数据。这意味着,重新启动后,您最终可能会遇到重复项。
如果您需要在应用程序上下文重启之间持久化元数据,则框架提供以下持久性 `MetadataStores`
-
PropertiesPersistingMetadataStore
`PropertiesPersistingMetadataStore` 由属性文件和 `PropertiesPersister` 支持。
默认情况下,它只在应用程序上下文正常关闭时持久化状态。它实现了 `Flushable`,因此您可以通过调用 `flush()` 来随意持久化状态。以下示例演示如何使用 XML 配置 'PropertiesPersistingMetadataStore'
<bean id="metadataStore"
class="org.springframework.integration.metadata.PropertiesPersistingMetadataStore"/>
或者,您可以提供您自己的 `MetadataStore` 接口实现(例如,`JdbcMetadataStore`),并将其配置为应用程序上下文中的 Bean。
从 4.0 版本开始,`SimpleMetadataStore`、`PropertiesPersistingMetadataStore` 和 `RedisMetadataStore` 实现 `ConcurrentMetadataStore`。这些提供原子更新,并且可以在多个组件或应用程序实例中使用。
幂等接收器和元数据存储
如果需要过滤已经处理的传入消息并将其丢弃或在丢弃时执行某些其他逻辑,则元数据存储对于实现 EIP 幂等接收器 模式非常有用。以下配置显示了如何执行此操作的示例
<int:filter input-channel="serviceChannel"
output-channel="idempotentServiceChannel"
discard-channel="discardChannel"
expression="@metadataStore.get(headers.businessKey) == null"/>
<int:publish-subscribe-channel id="idempotentServiceChannel"/>
<int:outbound-channel-adapter channel="idempotentServiceChannel"
expression="@metadataStore.put(headers.businessKey, '')"/>
<int:service-activator input-channel="idempotentServiceChannel" ref="service"/>
幂等条目的 `value` 可以是过期日期,在此日期之后,应由某些计划的清除程序从元数据存储中删除该条目。
另见 幂等接收器企业集成模式。
MetadataStoreListener
某些元数据存储(目前只有 Zookeeper)支持注册侦听器以在项目更改时接收事件,如下例所示
public interface MetadataStoreListener {
void onAdd(String key, String value);
void onRemove(String key, String oldValue);
void onUpdate(String key, String newValue);
}
有关更多信息,请参阅 Javadoc。如果您只对一部分事件感兴趣,可以对 `MetadataStoreListenerAdapter` 进行子类化。