Metadata Store
许多外部系统、服务或资源不是事务性的(Twitter、RSS、文件系统等),并且没有任何将数据标记为已读取的能力。此外,有时您可能需要在一些集成解决方案中实现 Enterprise Integration Pattern idempotent receiver。为了实现这一目标并存储端点与外部系统的下一次交互之前的某些先前状态或处理下一个消息,Spring Integration 提供元数据存储组件作为 org.springframework.integration.metadata.MetadataStore
接口的实现,并具有常规键值契约。
元数据存储旨在存储各种类型的一般元数据(例如,已处理的最后一个提要条目的已发布日期),以帮助提要适配器之类的组件处理重复项。如果未直接向组件提供对 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
。这些提供原子更新,可用于多个组件或应用程序实例。
Idempotent Receiver and Metadata Store
元数据存储在需要过滤传入消息(如果该消息已被处理,则可以将其丢弃或在丢弃时执行一些其他逻辑)时实现 EIP idempotent receiver 模式非常有用。以下配置显示了如何执行此操作的示例:
<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
进行子类化。