许多外部系统、服务或资源不是事务性的(Twitter、RSS、文件系统等),并且无法将数据标记为已读。
此外,有时,您可能需要在某些集成解决方案中实现 Enterprise Integration Pattern 幂等接收器。
为了实现这个目标并在与外部系统的下一次交互之前存储端点的一些先前状态或处理下一条消息, Spring 集成提供了元数据存储组件作为具有通用键值契约的接口的实现。org.springframework.integration.metadata.MetadataStore
元数据存储旨在存储各种类型的通用元数据(例如,已处理的最后一个源条目的发布日期),以帮助源适配器等组件处理重复项。
如果未直接向组件提供对 a 的引用,则查找元数据存储的算法如下:首先,在应用程序上下文中查找具有 ID 的 bean。
如果找到,请使用它。
否则,请创建一个新实例 ,该实例是一个内存中实现,它仅在当前正在运行的应用程序上下文的生命周期内保留元数据。
这意味着,在重新启动时,您最终可能会得到重复的条目。MetadataStore
metadataStore
SimpleMetadataStore
如果需要在应用程序上下文重新启动之间保留元数据,框架将提供以下持久性:MetadataStores
-
PropertiesPersistingMetadataStore
它由属性文件和 PropertiesPersister
提供支持。PropertiesPersistingMetadataStore
默认情况下,它仅在应用程序上下文正常关闭时保留状态。
它实现后,您可以通过调用 .
以下示例显示了如何使用 XML 配置 'PropertiesPersistingMetadataStore':Flushable
flush()
<bean id="metadataStore"
class="org.springframework.integration.metadata.PropertiesPersistingMetadataStore"/>
或者,您可以提供自己的接口实现(例如,),并在应用程序上下文中将其配置为 bean。MetadataStore
JdbcMetadataStore
从版本 4.0 开始,、 和 implement .
这些实例提供原子更新,并且可以跨多个组件或应用程序实例使用。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