对于最新的稳定版本,请使用 Spring Integration 6.3.1Spring中文文档

对于最新的稳定版本,请使用 Spring Integration 6.3.1Spring中文文档

这是一个实现,可以配置为单个消息端点,同时实际委托给其他处理程序链,例如过滤器、转换器、拆分器等。 当需要以固定的线性级数连接多个处理程序时,这可能会导致配置简单得多。 例如,在其他组件之前提供变压器是相当普遍的。 同样,当您在链中的其他一些组件之前提供过滤器时,您实质上会创建一个选择性使用者。 在任何一种情况下,链只需要一个 和 一个 ,无需为每个单独的组件定义通道。MessageHandlerChainMessageHandlerinput-channeloutput-channelSpring中文文档

这主要是为XML配置而设计的。 对于 Java DSL,定义可以被视为链组件,但它与下面本章中描述的概念和原则无关。 有关更多信息,请参见 Java DSLMessageHandlerChainIntegrationFlow
Spring Integration提供了一个布尔属性:。 在同一点对点信道上为多个选择性使用者提供不同的接受条件时,应将此值设置为“true”(默认值为 ),以便调度程序知道消息已被拒绝,并因此尝试将消息传递给其他订阅者。 如果未引发异常,则调度程序会认为消息已成功传递,即使筛选器已删除消息以防止进一步处理也是如此。 如果您确实想“删除”消息,过滤器的“discard-channel”可能很有用,因为它确实让您有机会对删除的消息执行一些操作(例如将其发送到 JMS 队列或将其写入日志)。FilterthrowExceptionOnRejectionfalse

处理程序链简化了配置,同时在内部保持组件之间相同程度的松耦合,如果在某些时候需要非线性排列,则修改配置是微不足道的。Spring中文文档

在内部,链被扩展为列出的端点的线性设置,由匿名通道隔开。 在链中不考虑回复通道标头。 只有在调用最后一个处理程序后,生成的消息才会转发到回复通道或链的输出通道。 由于此设置,除最后一个处理程序外,所有处理程序都必须实现接口(它提供“setOutputChannel()”方法)。 如果设置了 on,则最后一个处理程序只需要一个输出通道。MessageProduceroutputChannelMessageHandlerChainSpring中文文档

与其他端点一样,这是可选的。 如果链的末端有回复消息,则输出通道优先。 但是,如果它不可用,链处理程序将检查入站消息上的应答通道标头作为回退。output-channel

在大多数情况下,您不需要自己实现。 下一节将重点介绍链元素的命名空间支持。 大多数 Spring Integration 端点(如服务激活器和转换器)都适合在 .MessageHandlerMessageHandlerChainSpring中文文档

这主要是为XML配置而设计的。 对于 Java DSL,定义可以被视为链组件,但它与下面本章中描述的概念和原则无关。 有关更多信息,请参见 Java DSLMessageHandlerChainIntegrationFlow
Spring Integration提供了一个布尔属性:。 在同一点对点信道上为多个选择性使用者提供不同的接受条件时,应将此值设置为“true”(默认值为 ),以便调度程序知道消息已被拒绝,并因此尝试将消息传递给其他订阅者。 如果未引发异常,则调度程序会认为消息已成功传递,即使筛选器已删除消息以防止进一步处理也是如此。 如果您确实想“删除”消息,过滤器的“discard-channel”可能很有用,因为它确实让您有机会对删除的消息执行一些操作(例如将其发送到 JMS 队列或将其写入日志)。FilterthrowExceptionOnRejectionfalse
与其他端点一样,这是可选的。 如果链的末端有回复消息,则输出通道优先。 但是,如果它不可用,链处理程序将检查入站消息上的应答通道标头作为回退。output-channel

配置链

该元素提供属性。 如果链中的最后一个元素能够生成回复消息(可选),则它还支持一个属性。 然后,子元素是滤波器、转换器、分离器和服务激活器。 最后一个元素也可以是路由器或出站通道适配器。 以下示例显示了一个链定义:<chain>input-channeloutput-channelSpring中文文档

<int:chain input-channel="input" output-channel="output">
    <int:filter ref="someSelector" throw-exception-on-rejection="true"/>
    <int:header-enricher>
        <int:header name="thing1" value="thing2"/>
    </int:header-enricher>
    <int:service-activator ref="someService" method="someMethod"/>
</int:chain>

前面示例中使用的元素设置一个消息头,其值为 on the message。 标头扩充器是仅触及标头值的专用化。 您可以通过实现 a 来获得相同的结果,该 head 进行了 header 修改并将其作为 bean 连接,但 header-enricher 是一个更简单的选项。<header-enricher>thing1thing2TransformerMessageHandlerSpring中文文档

可以配置为消息流的最后一个“封闭式”使用者。 对于此解决方案,您可以将其放在<链>某个<outbound-channel-adapter>的末尾,如以下示例所示:<chain>Spring中文文档

<int:chain input-channel="input">
    <int-xml:marshalling-transformer marshaller="marshaller" result-type="StringResult" />
    <int:service-activator ref="someService" method="someMethod"/>
    <int:header-enricher>
        <int:header name="thing1" value="thing2"/>
    </int:header-enricher>
    <int:logging-channel-adapter level="INFO" log-full-message="true"/>
</int:chain>
不允许的属性和元素

某些属性(如 和 不允许)在链中使用的组件上指定。 轮询器子元素也是如此。orderinput-channelSpring中文文档

对于Spring Integration核心组件,XML架构本身会强制执行其中一些约束。 但是,对于非核心组件或您自己的自定义组件,这些约束由 XML 命名空间分析器强制执行,而不是由 XML 架构强制执行。Spring中文文档

这些 XML 命名空间解析器约束是在 Spring Integration 2.2 中添加的。 如果尝试使用不允许的属性和元素,XML 命名空间解析器将抛出 .BeanDefinitionParsingExceptionSpring中文文档

不允许的属性和元素

某些属性(如 和 不允许)在链中使用的组件上指定。 轮询器子元素也是如此。orderinput-channelSpring中文文档

对于Spring Integration核心组件,XML架构本身会强制执行其中一些约束。 但是,对于非核心组件或您自己的自定义组件,这些约束由 XML 命名空间分析器强制执行,而不是由 XML 架构强制执行。Spring中文文档

这些 XML 命名空间解析器约束是在 Spring Integration 2.2 中添加的。 如果尝试使用不允许的属性和元素,XML 命名空间解析器将抛出 .BeanDefinitionParsingExceptionSpring中文文档

使用“id”属性

从 Spring Integration 3.0 开始,如果为链元素指定了属性,则该元素的 Bean 名称是链和元素本身的组合。 没有属性的元素不会注册为 bean,但每个元素都会被赋予一个包含链的元素。 请看以下示例:ididididcomponentNameidSpring中文文档

<int:chain id="somethingChain" input-channel="input">
    <int:service-activator id="somethingService" ref="someService" method="someMethod"/>
    <int:object-to-json-transformer/>
</int:chain>

在前面的示例中:Spring中文文档

  • 根元素具有 'somethingChain'。 因此,实现(或 ,取决于类型)bean 将此值作为其 Bean 名称。<chain>idAbstractEndpointPollingConsumerEventDrivenConsumerinput-channelSpring中文文档

  • Bean 获取一个 Bean 别名 ('somethingChain.handler'),它允许从 .MessageHandlerChainBeanFactorySpring中文文档

  • 不是一个完全成熟的消息传递端点(它不是 或 )。 它是 . 在本例中,使用 注册的 Bean 名称是 'somethingChain$child.somethingService.handler'。<service-activator>PollingConsumerEventDrivenConsumerMessageHandler<chain>BeanFactorySpring中文文档

  • 这取相同的值,但没有“.handler”后缀。 它变为“somethingChain$child.somethingService”。componentNameServiceActivatingHandlerSpring中文文档

  • 最后一个子组件 , 没有属性。 它基于它在 . 在本例中,它是“somethingChain$child#1”。 (名称的最后一个元素是链中的顺序,以“#0”开头)。 请注意,此转换器未在应用程序上下文中注册为 Bean,因此它不会获得 . 但是,它的值可用于日志记录和其他目的。<chain><object-to-json-transformer>idcomponentName<chain>beanNamecomponentNameSpring中文文档

元素的属性允许它们有资格进行 JMX 导出,并且它们可以在消息历史记录中进行跟踪。 如前所述,您可以使用适当的 Bean 名称从 中访问它们。id<chain>BeanFactorySpring中文文档

在元素上提供显式属性以简化日志中子组件的标识并提供从 etc 对它们的访问是很有用的。id<chain>BeanFactory
在元素上提供显式属性以简化日志中子组件的标识并提供从 etc 对它们的访问是很有用的。id<chain>BeanFactory

从链内调用链

有时,您需要从链内对另一条链进行嵌套调用,然后返回并继续在原始链中执行。 为此,您可以通过包含 <gateway> 元素来使用邮件网关,如以下示例所示:Spring中文文档

<int:chain id="main-chain" input-channel="in" output-channel="out">
    <int:header-enricher>
      <int:header name="name" value="Many" />
    </int:header-enricher>
    <int:service-activator>
      <bean class="org.foo.SampleService" />
    </int:service-activator>
    <int:gateway request-channel="inputA"/>
</int:chain>

<int:chain id="nested-chain-a" input-channel="inputA">
    <int:header-enricher>
        <int:header name="name" value="Moe" />
    </int:header-enricher>
    <int:gateway request-channel="inputB"/>
    <int:service-activator>
        <bean class="org.foo.SampleService" />
    </int:service-activator>
</int:chain>

<int:chain id="nested-chain-b" input-channel="inputB">
    <int:header-enricher>
        <int:header name="name" value="Jack" />
    </int:header-enricher>
    <int:service-activator>
        <bean class="org.foo.SampleService" />
    </int:service-activator>
</int:chain>

在前面的示例中,由在那里配置的“gateway”元素在处理结束时调用。 而 在 中时,在标头扩充后对 a 进行调用。 然后,流返回以完成 中的执行。 最后,流返回到 。 在链中定义元素的嵌套版本时,它不需要该属性。 相反,它采用当前状态的消息,并将其放置在属性中定义的通道上。 当该网关启动的下游流完成时,a 将返回到网关并继续其在当前链中的旅程。nested-chain-amain-chainnested-chain-anested-chain-bnested-chain-bmain-chain<gateway>service-interfacerequest-channelMessageSpring中文文档