元数据存储
许多外部系统、服务或资源不支持事务(如 Twitter、RSS、文件系统等),且无法将数据标记为已读。
此外,在某些集成解决方案中,您可能需要实现企业集成模式 幂等接收器。
为了实现这一目标,并在与外部系统进行下一次交互之前存储端点的某些先前状态,或处理下一条消息,Spring Integration 提供了元数据存储组件,作为 org.springframework.integration.metadata.MetadataStore 接口的实现,遵循通用的键值契约。
元数据存储库旨在存储各种类型的通用元数据(例如,已处理的最后一个源条目的发布日期),以帮助源适配器等组件处理重复项。
如果某个组件未直接获得对 MetadataStore 的引用,则定位元数据存储库的算法如下:首先,在应用上下文中查找 ID 为 metadataStore 的 Bean。
如果找到,则使用该 Bean。
否则,创建 SimpleMetadataStore 的新实例,这是一个内存实现,仅在当前运行的应用上下文生命周期内持久化元数据。
这意味着,重启后您可能会遇到重复条目。
如果您需要在应用程序上下文重启之间持久化元数据,该框架提供以下持久的 MetadataStores:
-
PropertiesPersistingMetadataStore
Spring Cloud AWS 也提供了一个 DynamoDbMetadataStore。
The 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 类。