提交 cf2182f4 编写于 作者: 茶陵後's avatar 茶陵後 👍

#21 spring-integration cn header hfef remove

上级 22398f74
# AMQP 支持 # AMQP 支持
## [](#amqp)AMQP 支持 ## AMQP 支持
Spring 集成提供了用于通过使用高级消息队列协议接收和发送消息的通道适配器。 Spring 集成提供了用于通过使用高级消息队列协议接收和发送消息的通道适配器。
...@@ -42,7 +42,7 @@ Spring 鉴于所提供的 AMQP 通道适配器仅用于单向消息传递(发 ...@@ -42,7 +42,7 @@ Spring 鉴于所提供的 AMQP 通道适配器仅用于单向消息传递(发
小贴士:你应该熟悉[reference documentation of the Spring AMQP project](https://docs.spring.io/spring-amqp/reference/html/)。它提供了关于 Spring 与 AMQP 的集成的更深入的信息,特别是与 RabbitMQ 的集成。 小贴士:你应该熟悉[reference documentation of the Spring AMQP project](https://docs.spring.io/spring-amqp/reference/html/)。它提供了关于 Spring 与 AMQP 的集成的更深入的信息,特别是与 RabbitMQ 的集成。
### [](#amqp-inbound-channel-adapter)入站通道适配器 ### 入站通道适配器
下面的清单显示了 AMQP 入站通道适配器的可能配置选项: 下面的清单显示了 AMQP 入站通道适配器的可能配置选项:
...@@ -167,7 +167,7 @@ XML ...@@ -167,7 +167,7 @@ XML
从版本 5.5 开始,`AmqpInboundChannelAdapter`可以配置`org.springframework.amqp.rabbit.retry.MessageRecoverer`策略,当内部调用重试操作时,该策略在`RecoveryCallback`中使用。有关更多信息,请参见`setMessageRecoverer()`爪哇docs。 从版本 5.5 开始,`AmqpInboundChannelAdapter`可以配置`org.springframework.amqp.rabbit.retry.MessageRecoverer`策略,当内部调用重试操作时,该策略在`RecoveryCallback`中使用。有关更多信息,请参见`setMessageRecoverer()`爪哇docs。
#### [](#amqp-debatching)批处理消息 #### 批处理消息
有关批处理消息的更多信息,请参见[the Spring AMQP Documentation](https://docs.spring.io/spring-amqp/docs/current/reference/html/#template-batching) 有关批处理消息的更多信息,请参见[the Spring AMQP Documentation](https://docs.spring.io/spring-amqp/docs/current/reference/html/#template-batching)
...@@ -180,9 +180,9 @@ XML ...@@ -180,9 +180,9 @@ XML
| |当重试操作需要恢复时,必须在批处理中使用`org.springframework.amqp.rabbit.retry.MessageBatchRecoverer`。| | |当重试操作需要恢复时,必须在批处理中使用`org.springframework.amqp.rabbit.retry.MessageBatchRecoverer`。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------| |---|-------------------------------------------------------------------------------------------------------------------------------------------|
### [](#polled-inbound-channel-adapter)已调查的入站通道适配器 ### 已调查的入站通道适配器
#### [](#overview)概述 #### 概述
版本 5.0.1 引入了一个轮询通道适配器,允许你按需获取单个消息——例如,使用`MessageSourcePollingTemplate`或 Poller。有关更多信息,请参见[延迟确认可收集消息源](./polling-consumer.html#deferred-acks-message-source) 版本 5.0.1 引入了一个轮询通道适配器,允许你按需获取单个消息——例如,使用`MessageSourcePollingTemplate`或 Poller。有关更多信息,请参见[延迟确认可收集消息源](./polling-consumer.html#deferred-acks-message-source)
...@@ -221,13 +221,13 @@ XML ...@@ -221,13 +221,13 @@ XML
This adapter currently does not have XML configuration support. This adapter currently does not have XML configuration support.
``` ```
#### [](#amqp-polled-debatching)批处理消息 #### 批处理消息
[批处理消息](#amqp-debatching) [批处理消息](#amqp-debatching)
对于轮询的适配器,不存在侦听器容器,批处理的消息总是会被删除(如果`BatchingStrategy`支持这样做的话)。 对于轮询的适配器,不存在侦听器容器,批处理的消息总是会被删除(如果`BatchingStrategy`支持这样做的话)。
### [](#amqp-inbound-gateway)入站网关 ### 入站网关
入站网关支持入站通道适配器上的所有属性(除了“通道”被“请求通道”代替),以及一些附加属性。下面的清单显示了可用的属性: 入站网关支持入站通道适配器上的所有属性(除了“通道”被“请求通道”代替),以及一些附加属性。下面的清单显示了可用的属性:
...@@ -313,11 +313,11 @@ XML ...@@ -313,11 +313,11 @@ XML
从版本 5.5 开始,`AmqpInboundChannelAdapter`可以配置`org.springframework.amqp.rabbit.retry.MessageRecoverer`策略,当内部调用重试操作时,该策略在`RecoveryCallback`中使用。有关更多信息,请参见`setMessageRecoverer()`Javadocs。 从版本 5.5 开始,`AmqpInboundChannelAdapter`可以配置`org.springframework.amqp.rabbit.retry.MessageRecoverer`策略,当内部调用重试操作时,该策略在`RecoveryCallback`中使用。有关更多信息,请参见`setMessageRecoverer()`Javadocs。
#### [](#amqp-gateway-debatching)批处理消息 #### 批处理消息
[批处理消息](#amqp-debatching) [批处理消息](#amqp-debatching)
### [](#amqp-inbound-ack)入站端点确认模式 ### 入站端点确认模式
默认情况下,入站端点使用`AUTO`确认模式,这意味着当下游集成流完成(或者通过使用`QueueChannel``ExecutorChannel`将消息传递给另一个线程)时,容器会自动确认消息。将模式设置为`NONE`将配置消费者,使得完全不使用确认(代理在消息发送后立即自动确认消息)。将模式设置为`MANUAL`,可以让用户代码在处理过程中的另一个点确认消息。为了支持这一点,在此模式下,端点在`amqp_channel``amqp_deliveryTag`标题中分别提供`Channel``deliveryTag` 默认情况下,入站端点使用`AUTO`确认模式,这意味着当下游集成流完成(或者通过使用`QueueChannel``ExecutorChannel`将消息传递给另一个线程)时,容器会自动确认消息。将模式设置为`NONE`将配置消费者,使得完全不使用确认(代理在消息发送后立即自动确认消息)。将模式设置为`MANUAL`,可以让用户代码在处理过程中的另一个点确认消息。为了支持这一点,在此模式下,端点在`amqp_channel``amqp_deliveryTag`标题中分别提供`Channel``deliveryTag`
...@@ -348,11 +348,11 @@ public Object handle(@Payload String payload, @Header(AmqpHeaders.CHANNEL) Chann ...@@ -348,11 +348,11 @@ public Object handle(@Payload String payload, @Header(AmqpHeaders.CHANNEL) Chann
} }
``` ```
### [](#amqp-outbound-endpoints)出站端点 ### 出站端点
以下出站端点有许多类似的配置选项。从版本 5.2 开始,添加了`confirm-timeout`。通常,当启用了 Publisher Confirms 时,代理将快速返回一个 ACK(或 NACK),该 ACK 将被发送到相应的通道。如果在接收到确认之前关闭了通道,则 Spring AMQP 框架将合成 NACK。“丢失”ACK 永远不会发生,但是,如果你设置了此属性,则端点将定期检查它们,并在时间过去而未收到确认的情况下合成 NACK。 以下出站端点有许多类似的配置选项。从版本 5.2 开始,添加了`confirm-timeout`。通常,当启用了 Publisher Confirms 时,代理将快速返回一个 ACK(或 NACK),该 ACK 将被发送到相应的通道。如果在接收到确认之前关闭了通道,则 Spring AMQP 框架将合成 NACK。“丢失”ACK 永远不会发生,但是,如果你设置了此属性,则端点将定期检查它们,并在时间过去而未收到确认的情况下合成 NACK。
### [](#amqp-outbound-channel-adapter)出站通道适配器 ### 出站通道适配器
下面的示例显示了 AMQP 出站通道适配器的可用属性: 下面的示例显示了 AMQP 出站通道适配器的可用属性:
...@@ -436,7 +436,7 @@ XML ...@@ -436,7 +436,7 @@ XML
| |return-channel<br/><br/>使用`return-channel`需要一个`RabbitTemplate`,其`mandatory`属性设置为`true`,而`CachingConnectionFactory`属性设置为`true`<br/>当使用带有返回的多个出站端点时,每个端点都需要一个单独的`RabbitTemplate`。| | |return-channel<br/><br/>使用`return-channel`需要一个`RabbitTemplate`,其`mandatory`属性设置为`true`,而`CachingConnectionFactory`属性设置为`true`<br/>当使用带有返回的多个出站端点时,每个端点都需要一个单独的`RabbitTemplate`。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#amqp-outbound-gateway)出站网关 ### 出站网关
下面的清单显示了 AMQP 出站网关的可能属性: 下面的清单显示了 AMQP 出站网关的可能属性:
...@@ -536,7 +536,7 @@ XML ...@@ -536,7 +536,7 @@ XML
请注意,出站适配器和出站网关配置之间的唯一区别是`expectReply`属性的设置。 请注意,出站适配器和出站网关配置之间的唯一区别是`expectReply`属性的设置。
### [](#amqp-async-outbound-gateway)异步出站网关 ### 异步出站网关
在上一节中讨论的网关是同步的,因为发送线程被挂起,直到收到答复(或发生超时)。 Spring 集成版本 4.3 增加了一个异步网关,它使用 Spring AMQP 中的`AsyncRabbitTemplate`。当发送消息时,线程在发送操作完成后立即返回,当收到消息时,响应将在模板的侦听器容器线程上发送。当在 Poller 线程上调用网关时,这可能是有用的。该线程已被释放,并可用于框架中的其他任务。 在上一节中讨论的网关是同步的,因为发送线程被挂起,直到收到答复(或发生超时)。 Spring 集成版本 4.3 增加了一个异步网关,它使用 Spring AMQP 中的`AsyncRabbitTemplate`。当发送消息时,线程在发送操作完成后立即返回,当收到消息时,响应将在模板的侦听器容器线程上发送。当在 Poller 线程上调用网关时,这可能是有用的。该线程已被释放,并可用于框架中的其他任务。
...@@ -649,7 +649,7 @@ XML ...@@ -649,7 +649,7 @@ XML
| |RabbitTemplate<br/><br/>当你使用确认和返回时,我们建议将连接到`RabbitTemplate``AsyncRabbitTemplate`中的<br/>专用。否则,可能会遇到意想不到的副作用。| | |RabbitTemplate<br/><br/>当你使用确认和返回时,我们建议将连接到`RabbitTemplate``AsyncRabbitTemplate`中的<br/>专用。否则,可能会遇到意想不到的副作用。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#alternative-confirms-returns)发布者确认和返回的替代机制 ### 发布者确认和返回的替代机制
当连接工厂被配置为 Publisher 确认和返回时,上面的小节讨论了用于异步接收确认和返回的消息通道的配置。从版本 5.4 开始,有一个额外的机制,通常更容易使用。 当连接工厂被配置为 Publisher 确认和返回时,上面的小节讨论了用于异步接收确认和返回的消息通道的配置。从版本 5.4 开始,有一个额外的机制,通常更容易使用。
...@@ -674,11 +674,11 @@ catch { ... } ...@@ -674,11 +674,11 @@ catch { ... }
为了提高性能,你可能希望发送多条消息,然后等待确认,而不是一次发送一条消息。返回的消息是转换后的原始消息;你可以使用所需的任何附加数据进行子类`CorrelationData` 为了提高性能,你可能希望发送多条消息,然后等待确认,而不是一次发送一条消息。返回的消息是转换后的原始消息;你可以使用所需的任何附加数据进行子类`CorrelationData`
### [](#amqp-conversion-inbound)入站消息转换 ### 入站消息转换
到达通道适配器或网关的入站消息将使用消息转换器转换为`spring-messaging``Message<?>`有效负载。默认情况下,使用`SimpleMessageConverter`,它处理 Java 序列化和文本。默认情况下,标头使用`DefaultHeaderMapper.inboundMapper()`进行映射。如果发生了转换错误,并且没有定义错误通道,那么异常将被抛到容器中,并由侦听器容器的错误处理程序处理。默认的错误处理程序将转换错误视为致命错误,并且消息将被拒绝(如果队列是这样配置的,则将其路由到死信交换)。如果定义了错误通道,则`ErrorMessage`有效负载是一个`ListenerExecutionFailedException`,带有属性`failedMessage`(无法转换的 Spring AMQP 消息)和`cause`。如果容器`AcknowledgeMode``AUTO`(默认值),并且错误流在不抛出异常的情况下消耗错误,则将确认原始消息。如果错误流抛出一个异常,那么异常类型将与容器的错误处理程序一起,决定是否重新请求消息。如果容器配置为`AcknowledgeMode.MANUAL`,则有效负载是带有附加属性`channel``deliveryTag``ManualAckListenerExecutionFailedException`。这使得错误流能够为消息调用`basicAck``basicNack`(或`basicReject`)来控制其配置。 到达通道适配器或网关的入站消息将使用消息转换器转换为`spring-messaging``Message<?>`有效负载。默认情况下,使用`SimpleMessageConverter`,它处理 Java 序列化和文本。默认情况下,标头使用`DefaultHeaderMapper.inboundMapper()`进行映射。如果发生了转换错误,并且没有定义错误通道,那么异常将被抛到容器中,并由侦听器容器的错误处理程序处理。默认的错误处理程序将转换错误视为致命错误,并且消息将被拒绝(如果队列是这样配置的,则将其路由到死信交换)。如果定义了错误通道,则`ErrorMessage`有效负载是一个`ListenerExecutionFailedException`,带有属性`failedMessage`(无法转换的 Spring AMQP 消息)和`cause`。如果容器`AcknowledgeMode``AUTO`(默认值),并且错误流在不抛出异常的情况下消耗错误,则将确认原始消息。如果错误流抛出一个异常,那么异常类型将与容器的错误处理程序一起,决定是否重新请求消息。如果容器配置为`AcknowledgeMode.MANUAL`,则有效负载是带有附加属性`channel``deliveryTag``ManualAckListenerExecutionFailedException`。这使得错误流能够为消息调用`basicAck``basicNack`(或`basicReject`)来控制其配置。
### [](#content-type-conversion-outbound)出站消息转换 ### 出站消息转换
Spring AMQP1.4 引入了`ContentTypeDelegatingMessageConverter`,其中实际的转换器是基于传入的内容类型选择消息属性的。这可以由入站端点使用。 Spring AMQP1.4 引入了`ContentTypeDelegatingMessageConverter`,其中实际的转换器是基于传入的内容类型选择消息属性的。这可以由入站端点使用。
...@@ -716,17 +716,17 @@ Spring AMQP1.4 引入了`ContentTypeDelegatingMessageConverter`,其中实际 ...@@ -716,17 +716,17 @@ Spring AMQP1.4 引入了`ContentTypeDelegatingMessageConverter`,其中实际
| |从版本 5.0 开始,添加到出站消息的`MessageProperties`的标题永远不会被映射的标题覆盖(默认情况下)。<br/>以前,只有当消息转换器是`ContentTypeDelegatingMessageConverter`(在这种情况下,头是首先映射的,以便可以选择适当的转换器)。,对于其他转换器,例如`SimpleMessageConverter`,映射的标头覆盖了转换器添加的任何标头。<br/>当出站消息有一些剩余的`contentType`标头(可能来自入站通道适配器)时,这会导致问题。并且正确的出站`contentType`被错误地覆盖。<br/>解决方法是在将消息发送到出站端点之前使用头部过滤器删除头部。<br/><br/>但是,在某些情况下,需要使用以前的行为—例如,当`String`包含 JSON 的有效负载时,`SimpleMessageConverter`不知道内容,并将`contentType`消息属性设置为`text/plain`,但你的应用程序想要重写通过将发送到出站端点的消息的`contentType`头设置为`application/json`<br/>`ObjectToJsonTransformer`确实做到了这(默认情况下)。<br/><br/>现在在出站通道适配器和网关上(以及在 AMQP 支持的通道上)有一个名为`headersMappedLast`的属性。<br/>将其设置为`true`,以恢复覆盖转换器添加的属性的行为。<br/><br/>从 5.1.9 版本开始,类似的`replyHeadersMappedLast`是为`AmqpInboundGateway`提供的,当我们生成一个答复并想要覆盖由转换器填充的标题时。<br/>有关更多信息,请参见其 Javadocs。| | |从版本 5.0 开始,添加到出站消息的`MessageProperties`的标题永远不会被映射的标题覆盖(默认情况下)。<br/>以前,只有当消息转换器是`ContentTypeDelegatingMessageConverter`(在这种情况下,头是首先映射的,以便可以选择适当的转换器)。,对于其他转换器,例如`SimpleMessageConverter`,映射的标头覆盖了转换器添加的任何标头。<br/>当出站消息有一些剩余的`contentType`标头(可能来自入站通道适配器)时,这会导致问题。并且正确的出站`contentType`被错误地覆盖。<br/>解决方法是在将消息发送到出站端点之前使用头部过滤器删除头部。<br/><br/>但是,在某些情况下,需要使用以前的行为—例如,当`String`包含 JSON 的有效负载时,`SimpleMessageConverter`不知道内容,并将`contentType`消息属性设置为`text/plain`,但你的应用程序想要重写通过将发送到出站端点的消息的`contentType`头设置为`application/json`<br/>`ObjectToJsonTransformer`确实做到了这(默认情况下)。<br/><br/>现在在出站通道适配器和网关上(以及在 AMQP 支持的通道上)有一个名为`headersMappedLast`的属性。<br/>将其设置为`true`,以恢复覆盖转换器添加的属性的行为。<br/><br/>从 5.1.9 版本开始,类似的`replyHeadersMappedLast`是为`AmqpInboundGateway`提供的,当我们生成一个答复并想要覆盖由转换器填充的标题时。<br/>有关更多信息,请参见其 Javadocs。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#amqp-user-id)出站用户 ID ### 出站用户 ID
Spring AMQP 版本 1.6 引入了一种机制,以允许用于出站消息的默认用户 ID 的规范。始终可以设置`AmqpHeaders.USER_ID`标头,它现在优先于默认值。这对消息接收者可能很有用。对于入站消息,如果消息发布者设置了属性,则该属性在`AmqpHeaders.RECEIVED_USER_ID`标头中可用。注意 RabbitMQ[验证用户 ID 是连接的实际用户 ID,或者该连接允许模拟](https://www.rabbitmq.com/validated-user-id.html) Spring AMQP 版本 1.6 引入了一种机制,以允许用于出站消息的默认用户 ID 的规范。始终可以设置`AmqpHeaders.USER_ID`标头,它现在优先于默认值。这对消息接收者可能很有用。对于入站消息,如果消息发布者设置了属性,则该属性在`AmqpHeaders.RECEIVED_USER_ID`标头中可用。注意 RabbitMQ[验证用户 ID 是连接的实际用户 ID,或者该连接允许模拟](https://www.rabbitmq.com/validated-user-id.html)
要为出站消息配置默认的用户 ID,请在`RabbitTemplate`上对其进行配置,并将出站适配器或网关配置为使用该模板。类似地,要在回复中设置用户 ID 属性,请在入站网关中插入一个适当配置的模板。有关更多信息,请参见[Spring AMQP documentation](https://docs.spring.io/spring-amqp/reference/html/_reference.html#template-user-id) 要为出站消息配置默认的用户 ID,请在`RabbitTemplate`上对其进行配置,并将出站适配器或网关配置为使用该模板。类似地,要在回复中设置用户 ID 属性,请在入站网关中插入一个适当配置的模板。有关更多信息,请参见[Spring AMQP documentation](https://docs.spring.io/spring-amqp/reference/html/_reference.html#template-user-id)
### [](#amqp-delay)延迟消息交换 ### 延迟消息交换
Spring AMQP 支持[RabbitMQ 延迟消息交换插件](https://docs.spring.io/spring-amqp/reference/html/#delayed-message-exchange)。对于入站消息,`x-delay`标头映射到`AmqpHeaders.RECEIVED_DELAY`标头。设置`AMQPHeaders.DELAY`报头会在出站消息中设置相应的`x-delay`报头。你还可以在出站端点上指定`delay``delayExpression`属性(当使用 XML 配置时,`delay-expression`)。这些属性优先于`AmqpHeaders.DELAY`标头。 Spring AMQP 支持[RabbitMQ 延迟消息交换插件](https://docs.spring.io/spring-amqp/reference/html/#delayed-message-exchange)。对于入站消息,`x-delay`标头映射到`AmqpHeaders.RECEIVED_DELAY`标头。设置`AMQPHeaders.DELAY`报头会在出站消息中设置相应的`x-delay`报头。你还可以在出站端点上指定`delay``delayExpression`属性(当使用 XML 配置时,`delay-expression`)。这些属性优先于`AmqpHeaders.DELAY`标头。
### [](#amqp-channels)AMQP 支持的消息通道 ### AMQP 支持的消息通道
有两个消息通道实现可用。一种是点对点,另一种是发布订阅。这两个通道都为底层`AmqpTemplate``SimpleMessageListenerContainer`提供了广泛的配置属性(如本章前面所示的通道适配器和网关)。然而,我们在这里展示的示例具有最小的配置。探索 XML 模式以查看可用的属性。 有两个消息通道实现可用。一种是点对点,另一种是发布订阅。这两个通道都为底层`AmqpTemplate``SimpleMessageListenerContainer`提供了广泛的配置属性(如本章前面所示的通道适配器和网关)。然而,我们在这里展示的示例具有最小的配置。探索 XML 模式以查看可用的属性。
...@@ -760,7 +760,7 @@ Spring AMQP 支持[RabbitMQ 延迟消息交换插件](https://docs.spring.io/spr ...@@ -760,7 +760,7 @@ Spring AMQP 支持[RabbitMQ 延迟消息交换插件](https://docs.spring.io/spr
| |从版本 5.0 开始,poller 通道现在为指定的`receiveTimeout`阻塞 poller 线程(默认值为 1 秒)。<br/>以前,与其他`PollableChannel`实现不同,如果没有可用的消息,线程将立即返回到调度程序,与接收超时无关。<br/>拦截比使用`basicGet()`检索消息(没有超时)要贵一些,因为必须创建一个使用者来接收每个消息。<br/>要恢复以前的行为,请将 poller 的`receiveTimeout`设置为 0。| | |从版本 5.0 开始,poller 通道现在为指定的`receiveTimeout`阻塞 poller 线程(默认值为 1 秒)。<br/>以前,与其他`PollableChannel`实现不同,如果没有可用的消息,线程将立即返回到调度程序,与接收超时无关。<br/>拦截比使用`basicGet()`检索消息(没有超时)要贵一些,因为必须创建一个使用者来接收每个消息。<br/>要恢复以前的行为,请将 poller 的`receiveTimeout`设置为 0。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### [](#configuring-with-java-configuration)使用 Java 配置进行配置 #### 使用 Java 配置进行配置
下面的示例展示了如何使用 Java 配置来配置通道: 下面的示例展示了如何使用 Java 配置来配置通道:
...@@ -793,7 +793,7 @@ public AmqpChannelFactoryBean pubSub(ConnectionFactory connectionFactory) { ...@@ -793,7 +793,7 @@ public AmqpChannelFactoryBean pubSub(ConnectionFactory connectionFactory) {
} }
``` ```
#### [](#configuring-with-the-java-dsl)使用 Java DSL 进行配置 #### 使用 Java DSL 进行配置
下面的示例展示了如何使用 Java DSL 配置通道: 下面的示例展示了如何使用 Java DSL 配置通道:
...@@ -829,9 +829,9 @@ public IntegrationFlow pubSubInFlow(ConnectionFactory connectionFactory) { ...@@ -829,9 +829,9 @@ public IntegrationFlow pubSubInFlow(ConnectionFactory connectionFactory) {
} }
``` ```
### [](#amqp-message-headers)AMQP 消息头 ### AMQP 消息头
#### [](#overview-2)概述 #### 概述
Spring 集成 AMQP 适配器自动映射所有 AMQP 属性和标头。(这是从 4.3-以前,只有标准标题被映射的变化)。默认情况下,这些属性通过使用[`DefaultAmqpHeaderMapper`](https://DOCS. Spring.io/ Spring-integration/api/org/springframework/integration/amqp/support/defaultamqpheadermapper.html)来复制到 Spring Integration`MessageHeaders` Spring 集成 AMQP 适配器自动映射所有 AMQP 属性和标头。(这是从 4.3-以前,只有标准标题被映射的变化)。默认情况下,这些属性通过使用[`DefaultAmqpHeaderMapper`](https://DOCS. Spring.io/ Spring-integration/api/org/springframework/integration/amqp/support/defaultamqpheadermapper.html)来复制到 Spring Integration`MessageHeaders`
...@@ -919,7 +919,7 @@ AMQP[`MessageProperties`](https://DOCS. Spring.io/ Spring-amqp/api/org/springf ...@@ -919,7 +919,7 @@ AMQP[`MessageProperties`](https://DOCS. Spring.io/ Spring-amqp/api/org/springf
| |从版本 5.1 开始,`DefaultAmqpHeaderMapper`将分别回到映射`MessageHeaders.ID`和`MessageHeaders.TIMESTAMP`到`MessageProperties.messageId`和`MessageProperties.timestamp`,如果出站消息上不存在相应的`amqp_messageId`或`amqp_timestamp`标头。<br/>入站属性将像以前一样映射到`amqp_*`标头。<br/>当消息消费者使用有状态重试时,填充`messageId`属性是有用的。| | |从版本 5.1 开始,`DefaultAmqpHeaderMapper`将分别回到映射`MessageHeaders.ID`和`MessageHeaders.TIMESTAMP`到`MessageProperties.messageId`和`MessageProperties.timestamp`,如果出站消息上不存在相应的`amqp_messageId`或`amqp_timestamp`标头。<br/>入站属性将像以前一样映射到`amqp_*`标头。<br/>当消息消费者使用有状态重试时,填充`messageId`属性是有用的。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### [](#amqp-content-type)标题`contentType` #### 标题`contentType`
与其他头不同,`AmqpHeaders.CONTENT_TYPE`不带`amqp_`前缀;这允许在不同的技术之间透明地传递 ContentType 头。例如,发送到 RabbitMQ 队列的入站 HTTP 消息。 与其他头不同,`AmqpHeaders.CONTENT_TYPE`不带`amqp_`前缀;这允许在不同的技术之间透明地传递 ContentType 头。例如,发送到 RabbitMQ 队列的入站 HTTP 消息。
...@@ -927,7 +927,7 @@ AMQP[`MessageProperties`](https://DOCS. Spring.io/ Spring-amqp/api/org/springf ...@@ -927,7 +927,7 @@ AMQP[`MessageProperties`](https://DOCS. Spring.io/ Spring-amqp/api/org/springf
在版本 5.1 之前,这个头也被映射为`MessageProperties.headers`映射中的一个条目;这是不正确的,而且,该值可能是错误的,因为底层的 Spring AMQP 消息转换器可能已经更改了内容类型。这样的更改将反映在第一类`content_type`属性中,但不会反映在 RabbitMQ 头文件映射中。入站映射忽略了 headers 映射值。`contentType`不再映射到 headers 映射中的条目。 在版本 5.1 之前,这个头也被映射为`MessageProperties.headers`映射中的一个条目;这是不正确的,而且,该值可能是错误的,因为底层的 Spring AMQP 消息转换器可能已经更改了内容类型。这样的更改将反映在第一类`content_type`属性中,但不会反映在 RabbitMQ 头文件映射中。入站映射忽略了 headers 映射值。`contentType`不再映射到 headers 映射中的条目。
### [](#amqp-strict-ordering)严格的消息排序 ### 严格的消息排序
本节描述了入站和出站消息的消息排序。 本节描述了入站和出站消息的消息排序。
...@@ -935,7 +935,7 @@ AMQP[`MessageProperties`](https://DOCS. Spring.io/ Spring-amqp/api/org/springf ...@@ -935,7 +935,7 @@ AMQP[`MessageProperties`](https://DOCS. Spring.io/ Spring-amqp/api/org/springf
如果需要对入站消息进行严格排序,则必须将入站侦听器容器的`prefetchCount`属性配置为`1`。这是因为,如果一条消息失败并被重新传递,它将在已有的预取消息之后到达。自 Spring AMQP 版本 2.0 以来,`prefetchCount`默认为`250`,以提高性能。严格的订货要求是以性能下降为代价的。 如果需要对入站消息进行严格排序,则必须将入站侦听器容器的`prefetchCount`属性配置为`1`。这是因为,如果一条消息失败并被重新传递,它将在已有的预取消息之后到达。自 Spring AMQP 版本 2.0 以来,`prefetchCount`默认为`250`,以提高性能。严格的订货要求是以性能下降为代价的。
#### [](#outbound)出站 #### 出站
考虑以下集成流程: 考虑以下集成流程:
...@@ -971,7 +971,7 @@ public IntegrationFlow flow(RabbitTemplate template) { ...@@ -971,7 +971,7 @@ public IntegrationFlow flow(RabbitTemplate template) {
| |在下游流中不能有线程切换(`QueueChannel`,`ExecutorChannel`,以及其他)。| | |在下游流中不能有线程切换(`QueueChannel`,`ExecutorChannel`,以及其他)。|
|---|--------------------------------------------------------------------------------------------------------| |---|--------------------------------------------------------------------------------------------------------|
### [](#amqp-samples)AMQP 样本 ### AMQP 样本
要对 AMQP 适配器进行实验,请查看 Spring Integration Samples Git Repository 中可用的示例,网址为[https://github.com/SpringSource/spring-integration-samples](https://github.com/spring-projects/spring-integration-samples) 要对 AMQP 适配器进行实验,请查看 Spring Integration Samples Git Repository 中可用的示例,网址为[https://github.com/SpringSource/spring-integration-samples](https://github.com/spring-projects/spring-integration-samples)
......
# 配置 # 配置
## [](#configuration)配置 ## 配置
Spring 集成提供了许多配置选项。你选择哪一种选择取决于你的特殊需求,以及你更喜欢工作的级别。与 Spring 框架一般一样,你可以混合和匹配各种技术以适应手头的问题。例如,你可以为大多数配置选择基于 XSD 的名称空间,并将其与使用注释进行配置的几个对象结合在一起。两者尽可能地提供一致的命名。由 XSD 模式定义的 XML 元素与注释的名称匹配,并且这些 XML 元素的属性与注释属性的名称匹配。你也可以直接使用 API,但是我们希望大多数开发人员选择一个更高级别的选项,或者基于名称空间的配置和注释驱动的配置的组合。 Spring 集成提供了许多配置选项。你选择哪一种选择取决于你的特殊需求,以及你更喜欢工作的级别。与 Spring 框架一般一样,你可以混合和匹配各种技术以适应手头的问题。例如,你可以为大多数配置选择基于 XSD 的名称空间,并将其与使用注释进行配置的几个对象结合在一起。两者尽可能地提供一致的命名。由 XSD 模式定义的 XML 元素与注释的名称匹配,并且这些 XML 元素的属性与注释属性的名称匹配。你也可以直接使用 API,但是我们希望大多数开发人员选择一个更高级别的选项,或者基于名称空间的配置和注释驱动的配置的组合。
### [](#configuration-namespace)名称空间支持 ### 名称空间支持
你可以使用 XML 元素配置 Spring 集成组件,这些 XML 元素直接映射到 Enterprise 集成的术语和概念。在许多情况下,元素名与[*Enterprise 整合模式 *](https://www.enterpriseintegrationpatterns.com/)书中的元素名匹配。 你可以使用 XML 元素配置 Spring 集成组件,这些 XML 元素直接映射到 Enterprise 集成的术语和概念。在许多情况下,元素名与[*Enterprise 整合模式 *](https://www.enterpriseintegrationpatterns.com/)书中的元素名匹配。
...@@ -70,7 +70,7 @@ Spring 集成提供了许多其他名称空间。实际上,每个提供名称 ...@@ -70,7 +70,7 @@ Spring 集成提供了许多其他名称空间。实际上,每个提供名称
本参考手册在相应章节中提供了各种元素的具体示例。在这里,需要认识的主要问题是每个名称空间 URI 和模式位置的命名的一致性。 本参考手册在相应章节中提供了各种元素的具体示例。在这里,需要认识的主要问题是每个名称空间 URI 和模式位置的命名的一致性。
### [](#namespace-taskscheduler)配置任务调度程序 ### 配置任务调度程序
在 Spring 集成中,`ApplicationContext`扮演着消息总线的中心角色,你只需要考虑几个配置选项。首先,你可能想要控制中心`TaskScheduler`实例。你可以通过提供一个名为`taskScheduler`的 Bean 来实现此目的。这也被定义为一个常数,如下所示: 在 Spring 集成中,`ApplicationContext`扮演着消息总线的中心角色,你只需要考虑几个配置选项。首先,你可能想要控制中心`TaskScheduler`实例。你可以通过提供一个名为`taskScheduler`的 Bean 来实现此目的。这也被定义为一个常数,如下所示:
...@@ -96,7 +96,7 @@ IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME ...@@ -96,7 +96,7 @@ IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME
有关更多信息,请参见[错误处理](./error-handling.html#error-handling) 有关更多信息,请参见[错误处理](./error-handling.html#error-handling)
### [](#global-properties)全局属性 ### 全局属性
可以通过在 Classpath 上提供一个属性文件来覆盖某些全局框架属性。 可以通过在 Classpath 上提供一个属性文件来覆盖某些全局框架属性。
...@@ -141,7 +141,7 @@ spring.integration.readOnly.headers= ...@@ -141,7 +141,7 @@ spring.integration.readOnly.headers=
spring.integration.messagingTemplate.throwExceptionOnLateReply=true spring.integration.messagingTemplate.throwExceptionOnLateReply=true
``` ```
### [](#annotations)注释支持 ### 注释支持
除了对配置消息端点的 XML 命名空间的支持外,还可以使用注释。首先, Spring 集成提供了类级`@MessageEndpoint`作为原型注释,这意味着它本身用 Spring 的`@Component`注释,因此通过 Spring 的组件扫描自动识别为 Bean 定义。 除了对配置消息端点的 XML 命名空间的支持外,还可以使用注释。首先, Spring 集成提供了类级`@MessageEndpoint`作为原型注释,这意味着它本身用 Spring 的`@Component`注释,因此通过 Spring 的组件扫描自动识别为 Bean 定义。
...@@ -253,7 +253,7 @@ public class ThingService { ...@@ -253,7 +253,7 @@ public class ThingService {
| |在解析所提及的注释(当没有配置特定的通道 Bean 时)之后自动创建的通道和相应的消费者端点,在上下文初始化的末尾附近被声明为 bean。<br/>这些 bean**CAN**在其他服务中被自动连线,但它们必须用`@Lazy`注释标记,因为这些定义通常在正常的自动布线处理过程中还不可用。<br/><br/>```<br/>@Autowired<br/>@Lazy<br/>@Qualifier("someChannel")<br/>MessageChannel someChannel;<br/>...<br/><br/>@Bean<br/>Thing1 dependsOnSPCA(@Qualifier("someInboundAdapter") @Lazy SourcePollingChannelAdapter someInboundAdapter) {<br/> ...<br/>}<br/>```| | |在解析所提及的注释(当没有配置特定的通道 Bean 时)之后自动创建的通道和相应的消费者端点,在上下文初始化的末尾附近被声明为 bean。<br/>这些 bean**CAN**在其他服务中被自动连线,但它们必须用`@Lazy`注释标记,因为这些定义通常在正常的自动布线处理过程中还不可用。<br/><br/>```<br/>@Autowired<br/>@Lazy<br/>@Qualifier("someChannel")<br/>MessageChannel someChannel;<br/>...<br/><br/>@Bean<br/>Thing1 dependsOnSPCA(@Qualifier("someInboundAdapter") @Lazy SourcePollingChannelAdapter someInboundAdapter) {<br/> ...<br/>}<br/>```|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### [](#configuration-using-poller-annotation)使用`@Poller`注释 #### 使用`@Poller`注释
Spring Integration4.0 之前,消息传递注释要求`inputChannel`是对`SubscribableChannel`的引用。对于`PollableChannel`实例,需要一个`<int:bridge/>`元素来配置`<int:poller/>`并使复合端点为`PollingConsumer`。版本 4.0 引入了`@Poller`注释,以允许直接在消息传递注释上配置`poller`属性,如下例所示: Spring Integration4.0 之前,消息传递注释要求`inputChannel`是对`SubscribableChannel`的引用。对于`PollableChannel`实例,需要一个`<int:bridge/>`元素来配置`<int:poller/>`并使复合端点为`PollingConsumer`。版本 4.0 引入了`@Poller`注释,以允许直接在消息传递注释上配置`poller`属性,如下例所示:
...@@ -319,7 +319,7 @@ public class AnnotationService { ...@@ -319,7 +319,7 @@ public class AnnotationService {
消息传递注释上的`poller()`属性与`reactive()`属性是互斥的。有关更多信息,请参见下一节。 消息传递注释上的`poller()`属性与`reactive()`属性是互斥的。有关更多信息,请参见下一节。
#### [](#configuration-using-reactive-annotation)使用`@Reactive`注释 #### 使用`@Reactive`注释
`ReactiveStreamsConsumer`自版本 5.0 以来一直存在,但它仅在端点的输入通道是`FluxMessageChannel`(或任何`org.reactivestreams.Publisher`实现)时才应用。从版本 5.3 开始,当目标消息处理程序是独立于输入通道类型的`ReactiveMessageHandler`时,框架也会创建它的实例。对于从版本 5.5 开始的所有消息传递注释,都引入了`@Reactive`子注释(类似于上面提到的`@Poller`)。它接受一个可选的`Function<? super Flux<Message<?>>, ? extends Publisher<Message<?>>>` Bean 引用,并且独立于输入通道类型和消息处理程序,将目标端点转换为`ReactiveStreamsConsumer`实例。该函数使用来自`Flux.transform()`操作符的一些自定义(`publishOn()`,`doOnNext()`,`log()`,`retry()`等)在来自输入通道的反应流上应用。 `ReactiveStreamsConsumer`自版本 5.0 以来一直存在,但它仅在端点的输入通道是`FluxMessageChannel`(或任何`org.reactivestreams.Publisher`实现)时才应用。从版本 5.3 开始,当目标消息处理程序是独立于输入通道类型的`ReactiveMessageHandler`时,框架也会创建它的实例。对于从版本 5.5 开始的所有消息传递注释,都引入了`@Reactive`子注释(类似于上面提到的`@Poller`)。它接受一个可选的`Function<? super Flux<Message<?>>, ? extends Publisher<Message<?>>>` Bean 引用,并且独立于输入通道类型和消息处理程序,将目标端点转换为`ReactiveStreamsConsumer`实例。该函数使用来自`Flux.transform()`操作符的一些自定义(`publishOn()`,`doOnNext()`,`log()`,`retry()`等)在来自输入通道的反应流上应用。
...@@ -339,7 +339,7 @@ public void handleReactive(String payload) { ...@@ -339,7 +339,7 @@ public void handleReactive(String payload) {
消息传递注释上的`reactive()`属性与`poller()`属性是互斥的。有关更多信息,请参见[使用`@Poller`注释](#configuration-using-poller-annotation)和[反应流支持](./reactive-streams.html#reactive-streams)。 消息传递注释上的`reactive()`属性与`poller()`属性是互斥的。有关更多信息,请参见[使用`@Poller`注释](#configuration-using-poller-annotation)和[反应流支持](./reactive-streams.html#reactive-streams)。
#### [](#using-the-inboundchanneladapter-annotation)使用`@InboundChannelAdapter`注释 #### 使用`@InboundChannelAdapter`注释
版本 4.0 引入了`@InboundChannelAdapter`方法级注释。它为带注释的方法基于`MethodInvokingMessageSource`生成`SourcePollingChannelAdapter`集成组件。该注释类似于`<int:inbound-channel-adapter>`XML 组件,并且具有相同的限制:该方法不能具有参数,并且返回类型不能是`void`。它有两个属性:`value`(要求的`MessageChannel` Bean name)和`poller`(可选的`@Poller`注释,如[前面描述的](#configuration-using-poller-annotation))。如果需要提供一些`MessageHeaders`,使用`Message<?>`返回类型并使用`MessageBuilder`来构建`Message<?>`。使用`MessageBuilder`可以配置`MessageHeaders`。下面的示例展示了如何使用`@InboundChannelAdapter`注释: 版本 4.0 引入了`@InboundChannelAdapter`方法级注释。它为带注释的方法基于`MethodInvokingMessageSource`生成`SourcePollingChannelAdapter`集成组件。该注释类似于`<int:inbound-channel-adapter>`XML 组件,并且具有相同的限制:该方法不能具有参数,并且返回类型不能是`void`。它有两个属性:`value`(要求的`MessageChannel` Bean name)和`poller`(可选的`@Poller`注释,如[前面描述的](#configuration-using-poller-annotation))。如果需要提供一些`MessageHeaders`,使用`Message<?>`返回类型并使用`MessageBuilder`来构建`Message<?>`。使用`MessageBuilder`可以配置`MessageHeaders`。下面的示例展示了如何使用`@InboundChannelAdapter`注释:
...@@ -363,11 +363,11 @@ public String foo() { ...@@ -363,11 +363,11 @@ public String foo() {
参见[`@MessagingGateway`注释](./gateway.html#messaging-gateway-annotation)。 参见[`@MessagingGateway`注释](./gateway.html#messaging-gateway-annotation)。
#### [](#using-the-integrationcomponentscan-annotation)使用`@IntegrationComponentScan`注释 #### 使用`@IntegrationComponentScan`注释
标准的 Spring 框架`@ComponentScan`注释不扫描接口中的原型`@Component`注释。为了克服这个限制并允许`@MessagingGateway`的配置(参见[`@MessagingGateway`注释](./gateway.html#messaging-gateway-annotation)),我们引入了`@IntegrationComponentScan`机制。此注释必须与`@Configuration`注释一起放置,并进行自定义以定义其扫描选项,例如`basePackages`和`basePackageClasses`。在这种情况下,所有发现的带有`@MessagingGateway`注释的接口都被解析并注册为`GatewayProxyFactoryBean`实例。所有其他基于类的组件都由标准`@ComponentScan`解析。 标准的 Spring 框架`@ComponentScan`注释不扫描接口中的原型`@Component`注释。为了克服这个限制并允许`@MessagingGateway`的配置(参见[`@MessagingGateway`注释](./gateway.html#messaging-gateway-annotation)),我们引入了`@IntegrationComponentScan`机制。此注释必须与`@Configuration`注释一起放置,并进行自定义以定义其扫描选项,例如`basePackages`和`basePackageClasses`。在这种情况下,所有发现的带有`@MessagingGateway`注释的接口都被解析并注册为`GatewayProxyFactoryBean`实例。所有其他基于类的组件都由标准`@ComponentScan`解析。
### [](#meta-annotations)消息传递元注释 ### 消息传递元注释
从版本 4.0 开始,所有消息传递注释都可以配置为元注释,并且所有用户定义的消息传递注释都可以定义相同的属性来覆盖其默认值。此外,元注释可以按层次进行配置,如下例所示: 从版本 4.0 开始,所有消息传递注释都可以配置为元注释,并且所有用户定义的消息传递注释都可以定义相同的属性来覆盖其默认值。此外,元注释可以按层次进行配置,如下例所示:
...@@ -399,7 +399,7 @@ public Object service(Object payload) { ...@@ -399,7 +399,7 @@ public Object service(Object payload) {
分层配置元注释使用户可以为各种属性设置默认值,并使 Framework Java 依赖与用户注释隔离,从而避免在用户类中使用它们。如果框架找到了一个具有框架元注释的用户注释的方法,则将其视为直接使用框架注释对该方法进行了注释。 分层配置元注释使用户可以为各种属性设置默认值,并使 Framework Java 依赖与用户注释隔离,从而避免在用户类中使用它们。如果框架找到了一个具有框架元注释的用户注释的方法,则将其视为直接使用框架注释对该方法进行了注释。
#### [](#annotations_on_beans)方法上的注释 #### 方法上的注释
从版本 4.0 开始,你可以在`@Configuration`类中的`@Bean`方法定义上配置消息注释,以基于 bean 而不是方法生成消息端点。当`@Bean`定义是“开箱即用”`MessageHandler`实例(`AggregatingMessageHandler`,`DefaultMessageSplitter`,以及其他),`Transformer`实例(`JsonToObjectTransformer`,`ClaimCheckOutTransformer`,以及其他),以及`MessageSource`实例(`FileReadingMessageSource`,`RedisStoreMessageSource`,以及其他)时,它是有用的。下面的示例展示了如何使用带有`@Bean`注释的消息传递注释: 从版本 4.0 开始,你可以在`@Configuration`类中的`@Bean`方法定义上配置消息注释,以基于 bean 而不是方法生成消息端点。当`@Bean`定义是“开箱即用”`MessageHandler`实例(`AggregatingMessageHandler`,`DefaultMessageSplitter`,以及其他),`Transformer`实例(`JsonToObjectTransformer`,`ClaimCheckOutTransformer`,以及其他),以及`MessageSource`实例(`FileReadingMessageSource`,`RedisStoreMessageSource`,以及其他)时,它是有用的。下面的示例展示了如何使用带有`@Bean`注释的消息传递注释:
...@@ -477,7 +477,7 @@ public class MyFlowConfiguration { ...@@ -477,7 +477,7 @@ public class MyFlowConfiguration {
| |使用 Java 配置,你可以在`@Bean`方法级别上使用任何`@Conditional`(例如,`@Profile`)的定义来跳过 Bean 注册的某些条件原因。<br/>下面的示例展示了如何这样做:<br/><br/>```<br/>@Bean<br/>@ServiceActivator(inputChannel = "skippedChannel")<br/>@Profile("thing")<br/>public MessageHandler skipped() {<br/> return System.out::println;<br/>}<br/>```连同现有的容器逻辑一起,消息传递端点 Bean(基于`@ServiceActivator`注释)也未注册。| | |使用 Java 配置,你可以在`@Bean`方法级别上使用任何`@Conditional`(例如,`@Profile`)的定义来跳过 Bean 注册的某些条件原因。<br/>下面的示例展示了如何这样做:<br/><br/>```<br/>@Bean<br/>@ServiceActivator(inputChannel = "skippedChannel")<br/>@Profile("thing")<br/>public MessageHandler skipped() {<br/> return System.out::println;<br/>}<br/>```连同现有的容器逻辑一起,消息传递端点 Bean(基于`@ServiceActivator`注释)也未注册。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### [](#creating-a-bridge-with-annotations)创建带有注释的桥 #### 创建带有注释的桥
从版本 4.0 开始,Java Configuration 提供`@BridgeFrom`和`@BridgeTo``@Bean`方法注释,以便在`MessageChannel`类中标记`MessageChannel`bean。这些确实是为了完整性而存在的,提供了一种方便的机制来声明`BridgeHandler`及其消息端点配置: 从版本 4.0 开始,Java Configuration 提供`@BridgeFrom`和`@BridgeTo``@Bean`方法注释,以便在`MessageChannel`类中标记`MessageChannel`bean。这些确实是为了完整性而存在的,提供了一种方便的机制来声明`BridgeHandler`及其消息端点配置:
...@@ -506,15 +506,15 @@ public MessageChannel bridgeToInput() { ...@@ -506,15 +506,15 @@ public MessageChannel bridgeToInput() {
你也可以将这些注释用作元注释。 你也可以将这些注释用作元注释。
#### [](#advising-annotated-endpoints)通知带注释的端点 #### 通知带注释的端点
见[使用注释为端点提供建议](./handler-advice.html#advising-with-annotations)。 见[使用注释为端点提供建议](./handler-advice.html#advising-with-annotations)。
### [](#message-mapping-rules)消息映射规则和约定 ### 消息映射规则和约定
Spring 集成实现了一种灵活的功能,通过依赖一些默认规则和定义某些约定,在不提供额外配置的情况下将消息映射到方法及其参数。以下各节中的示例阐明了这些规则。 Spring 集成实现了一种灵活的功能,通过依赖一些默认规则和定义某些约定,在不提供额外配置的情况下将消息映射到方法及其参数。以下各节中的示例阐明了这些规则。
#### [](#sample-scenarios)示例场景 #### 示例场景
下面的示例显示了一个未注释的参数(对象或原语),它不是具有非空返回类型的`Map`或`Properties`对象: 下面的示例显示了一个未注释的参数(对象或原语),它不是具有非空返回类型的`Map`或`Properties`对象:
...@@ -580,7 +580,7 @@ public void soSomething(); ...@@ -580,7 +580,7 @@ public void soSomething();
这个示例与前面的示例相同,但不产生输出。 这个示例与前面的示例相同,但不产生输出。
#### [](#annotation-based-mapping)基于注释的映射 #### 基于注释的映射
基于注释的映射是将消息映射到方法的最安全、最不模糊的方法。下面的示例展示了如何显式地将方法映射到标头: 基于注释的映射是将消息映射到方法的最安全、最不模糊的方法。下面的示例展示了如何显式地将方法映射到标头:
...@@ -614,7 +614,7 @@ public String soSomething(@Headers Map m, @Header("something") Map f, @Header("s ...@@ -614,7 +614,7 @@ public String soSomething(@Headers Map m, @Header("something") Map f, @Header("s
这个示例将特别有问题,因为它的两个参数是`Map`实例。然而,使用基于注释的映射,可以很容易地避免歧义。在这个示例中,第一个参数映射到所有消息头,而第二个和第三个参数映射到名为“Something”和“Somethothing”的消息头的值。有效载荷没有被映射到任何参数。 这个示例将特别有问题,因为它的两个参数是`Map`实例。然而,使用基于注释的映射,可以很容易地避免歧义。在这个示例中,第一个参数映射到所有消息头,而第二个和第三个参数映射到名为“Something”和“Somethothing”的消息头的值。有效载荷没有被映射到任何参数。
#### [](#complex-scenarios)复杂情景 #### 复杂情景
下面的示例使用了多个参数: 下面的示例使用了多个参数:
......
此差异已折叠。
# Java DSL # Java DSL
## [](#java-dsl)Java DSL ## Java DSL
Spring 集成 Java 配置和 DSL 提供了一组方便的构建器和 Fluent API,允许你配置 Spring 来自 Spring `@Configuration`类的集成消息流。 Spring 集成 Java 配置和 DSL 提供了一组方便的构建器和 Fluent API,允许你配置 Spring 来自 Spring `@Configuration`类的集成消息流。
...@@ -43,7 +43,7 @@ public class MyConfiguration { ...@@ -43,7 +43,7 @@ public class MyConfiguration {
前面的配置示例的结果是,它在`ApplicationContext`启动后创建 Spring 集成端点和消息通道。Java 配置既可以用来替换 XML 配置,也可以用来增强 XML 配置。你不需要替换所有现有的 XML 配置来使用 Java 配置。 前面的配置示例的结果是,它在`ApplicationContext`启动后创建 Spring 集成端点和消息通道。Java 配置既可以用来替换 XML 配置,也可以用来增强 XML 配置。你不需要替换所有现有的 XML 配置来使用 Java 配置。
### [](#java-dsl-basics)DSL 基础知识 ### DSL 基础知识
`org.springframework.integration.dsl`包包含前面提到的`IntegrationFlowBuilder`API 和许多`IntegrationComponentSpec`实现,它们也是构建器,并提供 Fluent API 来配置具体的端点。`IntegrationFlowBuilder`基础架构为基于消息的应用程序(例如通道、端点、poller 和通道拦截器)提供了常见的[Enterprise 整合模式](https://www.enterpriseintegrationpatterns.com/) `org.springframework.integration.dsl`包包含前面提到的`IntegrationFlowBuilder`API 和许多`IntegrationComponentSpec`实现,它们也是构建器,并提供 Fluent API 来配置具体的端点。`IntegrationFlowBuilder`基础架构为基于消息的应用程序(例如通道、端点、poller 和通道拦截器)提供了常见的[Enterprise 整合模式](https://www.enterpriseintegrationpatterns.com/)
...@@ -97,7 +97,7 @@ public IntegrationFlow myFlow() { ...@@ -97,7 +97,7 @@ public IntegrationFlow myFlow() {
| |Bean 定义重写<br/><br/>该 Java DSL 可以为在流定义中在线定义的对象注册 bean,并且可以重用现有的、注入的 bean。<br/>在为在线对象定义的名称与现有的 Bean 定义相同的情况下,抛出一个`BeanDefinitionOverrideException`,表示这样的配置是错误的。<br/>但是,当你处理`prototype`bean 时,没有办法从集成流处理器中检测到现有的 Bean 定义,因为每次我们从`BeanFactory`调用`prototype` Bean 时,都会得到一个新的实例。<br/>这样,在`IntegrationFlow`中就会使用所提供的实例。正如没有任何 Bean 注册和任何可能的检查现有的`prototype` Bean 定义。<br/>但是`BeanFactory.initializeBean()`是为这个对象调用的,如果它有一个显式的`id`并且 Bean 这个名称的定义在`prototype`范围内。| | |Bean 定义重写<br/><br/>该 Java DSL 可以为在流定义中在线定义的对象注册 bean,并且可以重用现有的、注入的 bean。<br/>在为在线对象定义的名称与现有的 Bean 定义相同的情况下,抛出一个`BeanDefinitionOverrideException`,表示这样的配置是错误的。<br/>但是,当你处理`prototype`bean 时,没有办法从集成流处理器中检测到现有的 Bean 定义,因为每次我们从`BeanFactory`调用`prototype` Bean 时,都会得到一个新的实例。<br/>这样,在`IntegrationFlow`中就会使用所提供的实例。正如没有任何 Bean 注册和任何可能的检查现有的`prototype` Bean 定义。<br/>但是`BeanFactory.initializeBean()`是为这个对象调用的,如果它有一个显式的`id`并且 Bean 这个名称的定义在`prototype`范围内。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#java-dsl-channels)消息通道 ### 消息通道
除了带有 EIP 方法的`IntegrationFlowBuilder`之外,Java DSL 还提供了一个 Fluent API 来配置`MessageChannel`实例。为此,提供了`MessageChannels`建设者工厂。下面的示例展示了如何使用它: 除了带有 EIP 方法的`IntegrationFlowBuilder`之外,Java DSL 还提供了一个 Fluent API 来配置`MessageChannel`实例。为此,提供了`MessageChannels`建设者工厂。下面的示例展示了如何使用它:
...@@ -180,7 +180,7 @@ Could not register object [queueChannel] under bean name 'queueChannel': ...@@ -180,7 +180,7 @@ Could not register object [queueChannel] under bean name 'queueChannel':
要使其工作,你需要为该通道声明`@Bean`,并从不同的`IntegrationFlow`实例中使用其 Bean 方法。 要使其工作,你需要为该通道声明`@Bean`,并从不同的`IntegrationFlow`实例中使用其 Bean 方法。
### [](#java-dsl-pollers)调查者 ### 调查者
Spring 集成还提供了一个 Fluent API,它允许你为`PollerMetadata`实现配置`AbstractPollingEndpoint`。你可以使用`Pollers`Builder 工厂来配置公共 Bean 定义或从`IntegrationFlowBuilder`EIP 方法创建的定义,如下例所示: Spring 集成还提供了一个 Fluent API,它允许你为`PollerMetadata`实现配置`AbstractPollingEndpoint`。你可以使用`Pollers`Builder 工厂来配置公共 Bean 定义或从`IntegrationFlowBuilder`EIP 方法创建的定义,如下例所示:
...@@ -197,7 +197,7 @@ public PollerSpec poller() { ...@@ -197,7 +197,7 @@ public PollerSpec poller() {
| |如果使用 DSL 构造`PollerSpec`作为`@Bean`,请不要调用 Bean 定义中的`get()`方法。<br/>`PollerSpec`是一个`FactoryBean`,它从规范中生成`PollerMetadata`对象并初始化其所有属性。| | |如果使用 DSL 构造`PollerSpec`作为`@Bean`,请不要调用 Bean 定义中的`get()`方法。<br/>`PollerSpec`是一个`FactoryBean`,它从规范中生成`PollerMetadata`对象并初始化其所有属性。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#java-dsl-reactive)the`reactive()`端点 ### `端点
从版本 5.5 开始,`ConsumerEndpointSpec`提供了一个`reactive()`配置属性,并带有一个可选的定制程序`Function<? super Flux<Message<?>>, ? extends Publisher<Message<?>>>`。此选项将目标端点配置为`ReactiveStreamsConsumer`实例,独立于输入通道类型,该类型通过`IntegrationReactiveUtils.messageChannelToFlux()`转换为`Flux`。所提供的函数是使用来自`Flux.transform()`的操作符来自定义(`publishOn()``log()``doOnNext()`等)来自输入通道的反应流的源。 从版本 5.5 开始,`ConsumerEndpointSpec`提供了一个`reactive()`配置属性,并带有一个可选的定制程序`Function<? super Flux<Message<?>>, ? extends Publisher<Message<?>>>`。此选项将目标端点配置为`ReactiveStreamsConsumer`实例,独立于输入通道类型,该类型通过`IntegrationReactiveUtils.messageChannelToFlux()`转换为`Flux`。所提供的函数是使用来自`Flux.transform()`的操作符来自定义(`publishOn()``log()``doOnNext()`等)来自输入通道的反应流的源。
...@@ -216,7 +216,7 @@ public IntegrationFlow reactiveEndpointFlow() { ...@@ -216,7 +216,7 @@ public IntegrationFlow reactiveEndpointFlow() {
有关更多信息,请参见[反应流支持](./reactive-streams.html#reactive-streams) 有关更多信息,请参见[反应流支持](./reactive-streams.html#reactive-streams)
### [](#java-dsl-endpoints)DSL 和端点配置 ### DSL 和端点配置
所有`IntegrationFlowBuilder`EIP 方法都有一个变体,该变体应用 lambda 参数为`AbstractEndpoint`实例提供选项:`SmartLifecycle``PollerMetadata``request-handler-advice-chain`和其他实例。每个参数都有通用参数,因此它允许你在上下文中配置一个端点,甚至它的`MessageHandler`,如下例所示: 所有`IntegrationFlowBuilder`EIP 方法都有一个变体,该变体应用 lambda 参数为`AbstractEndpoint`实例提供选项:`SmartLifecycle``PollerMetadata``request-handler-advice-chain`和其他实例。每个参数都有通用参数,因此它允许你在上下文中配置一个端点,甚至它的`MessageHandler`,如下例所示:
...@@ -254,7 +254,7 @@ public IntegrationFlow clientTcpFlow() { ...@@ -254,7 +254,7 @@ public IntegrationFlow clientTcpFlow() {
即它们不是合并的,在这种情况下只使用`testAdvice()` Bean。 即它们不是合并的,在这种情况下只使用`testAdvice()` Bean。
### [](#java-dsl-transformers)变形金刚 ### 变形金刚
DSL API 提供了一个方便的、fluent`Transformers`工厂,可用作`.transform()`EIP 方法中的内联目标对象定义。下面的示例展示了如何使用它: DSL API 提供了一个方便的、fluent`Transformers`工厂,可用作`.transform()`EIP 方法中的内联目标对象定义。下面的示例展示了如何使用它:
...@@ -274,7 +274,7 @@ public IntegrationFlow transformFlow() { ...@@ -274,7 +274,7 @@ public IntegrationFlow transformFlow() {
另请参见[lambdas 和`Message<?>`参数]。 另请参见[lambdas 和`Message<?>`参数]。
### [](#java-dsl-inbound-adapters)入站通道适配器 ### 入站通道适配器
通常,消息流从入站通道适配器开始(例如`<int-jdbc:inbound-channel-adapter>`)。适配器配置为`<poller>`,并要求`MessageSource<?>`定期生成消息。Java DSL 也允许从`MessageSource<?>`开始`IntegrationFlow`。为此,`IntegrationFlows`Builder 工厂提供了一个重载的`IntegrationFlows.from(MessageSource<?> messageSource)`方法。你可以将`MessageSource<?>`配置为 Bean,并将其作为该方法的参数。`IntegrationFlows.from()`的第二个参数是一个`Consumer<SourcePollingChannelAdapterSpec>`lambda,它允许你为`PollerMetadata``SmartLifecycle`提供选项。下面的示例展示了如何使用 Fluent API 和 lambda 来创建`IntegrationFlow`: 通常,消息流从入站通道适配器开始(例如`<int-jdbc:inbound-channel-adapter>`)。适配器配置为`<poller>`,并要求`MessageSource<?>`定期生成消息。Java DSL 也允许从`MessageSource<?>`开始`IntegrationFlow`。为此,`IntegrationFlows`Builder 工厂提供了一个重载的`IntegrationFlows.from(MessageSource<?> messageSource)`方法。你可以将`MessageSource<?>`配置为 Bean,并将其作为该方法的参数。`IntegrationFlows.from()`的第二个参数是一个`Consumer<SourcePollingChannelAdapterSpec>`lambda,它允许你为`PollerMetadata``SmartLifecycle`提供选项。下面的示例展示了如何使用 Fluent API 和 lambda 来创建`IntegrationFlow`:
...@@ -296,7 +296,7 @@ public IntegrationFlow pollingFlow() { ...@@ -296,7 +296,7 @@ public IntegrationFlow pollingFlow() {
对于那些不需要直接构建`Message`对象的情况,可以使用基于`java.util.function.Supplier``IntegrationFlows.fromSupplier()`变体。`Supplier.get()`的结果会自动包装在`Message`中(如果它还不是`Message`)。 对于那些不需要直接构建`Message`对象的情况,可以使用基于`java.util.function.Supplier``IntegrationFlows.fromSupplier()`变体。`Supplier.get()`的结果会自动包装在`Message`中(如果它还不是`Message`)。
### [](#java-dsl-routers)消息路由器 ### 消息路由器
Spring 集成原生地提供了专门的路由器类型,包括: Spring 集成原生地提供了专门的路由器类型,包括:
...@@ -366,7 +366,7 @@ public IntegrationFlow recipientListFlow() { ...@@ -366,7 +366,7 @@ public IntegrationFlow recipientListFlow() {
另请参见[lambdas 和`Message<?>`参数]。 另请参见[lambdas 和`Message<?>`参数]。
### [](#java-dsl-splitters)分离器 ### 分离器
要创建拆分器,请使用`split()`EIP 方法。默认情况下,如果有效负载是`Iterable``Iterator``Array``Stream`或活性`Publisher`,则`split()`方法将每个项输出为单独的消息。它接受 lambda、spel 表达式或任何`AbstractMessageSplitter`实现。或者,你可以使用它而不需要参数来提供`DefaultMessageSplitter`。下面的示例展示了如何通过提供 lambda 来使用`split()`方法: 要创建拆分器,请使用`split()`EIP 方法。默认情况下,如果有效负载是`Iterable``Iterator``Array``Stream`或活性`Publisher`,则`split()`方法将每个项输出为单独的消息。它接受 lambda、spel 表达式或任何`AbstractMessageSplitter`实现。或者,你可以使用它而不需要参数来提供`DefaultMessageSplitter`。下面的示例展示了如何通过提供 lambda 来使用`split()`方法:
...@@ -384,7 +384,7 @@ public IntegrationFlow splitFlow() { ...@@ -384,7 +384,7 @@ public IntegrationFlow splitFlow() {
另请参见[lambdas 和`Message<?>`参数]。 另请参见[lambdas 和`Message<?>`参数]。
### [](#java-dsl-aggregators)聚合器和重排序程序 ### 聚合器和重排序程序
`Aggregator`在概念上与`Splitter`相反。它将单个消息的序列聚合到单个消息中,并且必然更复杂。默认情况下,聚合器返回一条包含来自传入消息的有效负载集合的消息。同样的规则也适用于`Resequencer`。下面的示例展示了拆分器-聚合器模式的典型示例: `Aggregator`在概念上与`Splitter`相反。它将单个消息的序列聚合到单个消息中,并且必然更复杂。默认情况下,聚合器返回一条包含来自传入消息的有效负载集合的消息。同样的规则也适用于`Resequencer`。下面的示例展示了拆分器-聚合器模式的典型示例:
...@@ -415,7 +415,7 @@ public IntegrationFlow splitAggregateFlow() { ...@@ -415,7 +415,7 @@ public IntegrationFlow splitAggregateFlow() {
对于`resequence()`EIP 方法,提供了类似的 lambda 配置。 对于`resequence()`EIP 方法,提供了类似的 lambda 配置。
### [](#java-dsl-handle)服务激活器和`.handle()`方法 ### `方法
`.handle()`EIP 方法的目标是在某些 POJO 上调用任何`MessageHandler`实现或任何方法。另一种选择是使用 lambda 表达式来定义“活动”。因此,我们引入了一个通用的`GenericHandler<P>`功能接口。它的`handle`方法需要两个参数:`P payload``MessageHeaders headers`(从版本 5.1 开始)。有了这一点,我们可以将流定义如下: `.handle()`EIP 方法的目标是在某些 POJO 上调用任何`MessageHandler`实现或任何方法。另一种选择是使用 lambda 表达式来定义“活动”。因此,我们引入了一个通用的`GenericHandler<P>`功能接口。它的`handle`方法需要两个参数:`P payload``MessageHeaders headers`(从版本 5.1 开始)。有了这一点,我们可以将流定义如下:
...@@ -461,7 +461,7 @@ public IntegrationFlow integerFlow() { ...@@ -461,7 +461,7 @@ public IntegrationFlow integerFlow() {
另请参见[lambdas 和`Message<?>`参数]。 另请参见[lambdas 和`Message<?>`参数]。
### [](#java-dsl-gateway)运营商网关() ### 运营商网关()
`IntegrationFlow`定义中的`gateway()`运算符是一种特殊的服务激活器实现,通过其输入通道调用一些其他端点或集成流并等待应答。从技术上讲,它在`<chain>`定义中扮演与嵌套`<gateway>`组件相同的角色(参见[从一条链子中调用一条链子](./chain.html#chain-gateway)),并允许流更干净、更直接。从逻辑上和业务角度来看,它是一个消息传递网关,允许在目标集成解决方案的不同部分之间分配和重用功能(参见[消息传递网关](./gateway.html#gateway))。对于不同的目标,这个操作符有几个重载: `IntegrationFlow`定义中的`gateway()`运算符是一种特殊的服务激活器实现,通过其输入通道调用一些其他端点或集成流并等待应答。从技术上讲,它在`<chain>`定义中扮演与嵌套`<gateway>`组件相同的角色(参见[从一条链子中调用一条链子](./chain.html#chain-gateway)),并允许流更干净、更直接。从逻辑上和业务角度来看,它是一个消息传递网关,允许在目标集成解决方案的不同部分之间分配和重用功能(参见[消息传递网关](./gateway.html#gateway))。对于不同的目标,这个操作符有几个重载:
...@@ -493,7 +493,7 @@ private static IntegrationFlow subFlow() { ...@@ -493,7 +493,7 @@ private static IntegrationFlow subFlow() {
| |如果下游流并不总是返回一个响应,你应该将`requestTimeout`设置为 0,以防止无限期地挂起调用线程。<br/>在这种情况下,流将在该点结束,线程将被释放以进行进一步的工作。| | |如果下游流并不总是返回一个响应,你应该将`requestTimeout`设置为 0,以防止无限期地挂起调用线程。<br/>在这种情况下,流将在该点结束,线程将被释放以进行进一步的工作。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#java-dsl-log)运算符日志() ### 运算符日志()
为了方便起见,为了记录通过 Spring 集成流(`<logging-channel-adapter>`)的消息行程,呈现了一个`log()`操作符。在内部,它由`WireTap``ChannelInterceptor`表示,其订阅服务器为`LoggingHandler`。它负责将传入消息记录到下一个端点或当前通道中。下面的示例展示了如何使用`LoggingHandler`: 为了方便起见,为了记录通过 Spring 集成流(`<logging-channel-adapter>`)的消息行程,呈现了一个`log()`操作符。在内部,它由`WireTap``ChannelInterceptor`表示,其订阅服务器为`LoggingHandler`。它负责将传入消息记录到下一个端点或当前通道中。下面的示例展示了如何使用`LoggingHandler`:
...@@ -507,7 +507,7 @@ private static IntegrationFlow subFlow() { ...@@ -507,7 +507,7 @@ private static IntegrationFlow subFlow() {
当这个操作符在流程的末尾使用时,它是单向处理程序,流程结束。要使其成为一个产生回复的流,你可以在`log()`之后使用一个简单的`bridge()`,或者,从版本 5.1 开始,你可以使用一个`logAndReply()`操作符。`logAndReply`只能在流的末尾使用。 当这个操作符在流程的末尾使用时,它是单向处理程序,流程结束。要使其成为一个产生回复的流,你可以在`log()`之后使用一个简单的`bridge()`,或者,从版本 5.1 开始,你可以使用一个`logAndReply()`操作符。`logAndReply`只能在流的末尾使用。
### [](#java-dsl-intercept)操作符截获() ### 操作符截获()
从版本 5.3 开始,`intercept()`操作符允许在流程中的当前`ChannelInterceptor`处注册一个或多个`ChannelInterceptor`实例。这是通过`MessageChannels`API 创建显式`MessageChannel`API 的一种替代方法。下面的示例使用`MessageSelectingInterceptor`来拒绝某些异常消息: 从版本 5.3 开始,`intercept()`操作符允许在流程中的当前`ChannelInterceptor`处注册一个或多个`ChannelInterceptor`实例。这是通过`MessageChannels`API 创建显式`MessageChannel`API 的一种替代方法。下面的示例使用`MessageSelectingInterceptor`来拒绝某些异常消息:
...@@ -517,7 +517,7 @@ private static IntegrationFlow subFlow() { ...@@ -517,7 +517,7 @@ private static IntegrationFlow subFlow() {
.handle(...) .handle(...)
``` ```
### [](#java-dsl-wiretap)`MessageChannelSpec.wireTap()` ### `
Spring 集成包括`.wireTap()`Fluent API`MessageChannelSpec`Builders。下面的示例展示了如何使用`wireTap`方法记录输入: Spring 集成包括`.wireTap()`Fluent API`MessageChannelSpec`Builders。下面的示例展示了如何使用`wireTap`方法记录输入:
...@@ -547,7 +547,7 @@ public IntegrationFlow loggingFlow() { ...@@ -547,7 +547,7 @@ public IntegrationFlow loggingFlow() {
在前面的示例中(并且在没有信道被声明的任何时间),隐式的`DirectChannel`被注入在`IntegrationFlow`的当前位置中,并用作当前配置的`ServiceActivatingHandler`的输出信道(来自`.handle()`,[前面描述的](#java-dsl-handle))。 在前面的示例中(并且在没有信道被声明的任何时间),隐式的`DirectChannel`被注入在`IntegrationFlow`的当前位置中,并用作当前配置的`ServiceActivatingHandler`的输出信道(来自`.handle()`,[前面描述的](#java-dsl-handle))。
### [](#java-dsl-flows)处理消息流 ### 处理消息流
`IntegrationFlowBuilder`提供了一个顶级 API 来生成连接到消息流的集成组件。当你的集成可以用单个流(通常是这种情况)来完成时,这是很方便的。交替地`IntegrationFlow`实例可以通过`MessageChannel`实例进行连接。 `IntegrationFlowBuilder`提供了一个顶级 API 来生成连接到消息流的集成组件。当你的集成可以用单个流(通常是这种情况)来完成时,这是很方便的。交替地`IntegrationFlow`实例可以通过`MessageChannel`实例进行连接。
...@@ -572,7 +572,7 @@ public IntegrationFlow lambdaFlow() { ...@@ -572,7 +572,7 @@ public IntegrationFlow lambdaFlow() {
从版本 5.0.6 开始,在`IntegrationFlow`中为组件生成的 Bean 名称包括流 Bean,后面跟着一个点(`.`)作为前缀。例如,前面示例中的`ConsumerEndpointFactoryBean`的`.transform("Hello "::concat)`的结果是 Bean 名称`lambdaFlow.o.s.i.config.ConsumerEndpointFactoryBean#0`。(`o.s.i`是从`org.springframework.integration`到适合页面的缩写。)该端点的`Transformer`实现 Bean 的 Bean 名称为`lambdaFlow.transformer#0`(从版本 5.1 开始),其中使用的是其组件类型,而不是`MethodInvokingTransformer`类的完全限定名称。当必须在流中生成 Bean 名称时,对所有`NamedComponent`s 应用相同的模式。 Bean 这些生成的名称与流 ID 一起前置,以用于诸如解析日志或在某些分析工具中将组件分组在一起的目的,以及在运行时并发注册集成流时避免竞争条件。有关更多信息,请参见[动态和运行时集成流](#java-dsl-runtime-flows)。 从版本 5.0.6 开始,在`IntegrationFlow`中为组件生成的 Bean 名称包括流 Bean,后面跟着一个点(`.`)作为前缀。例如,前面示例中的`ConsumerEndpointFactoryBean`的`.transform("Hello "::concat)`的结果是 Bean 名称`lambdaFlow.o.s.i.config.ConsumerEndpointFactoryBean#0`。(`o.s.i`是从`org.springframework.integration`到适合页面的缩写。)该端点的`Transformer`实现 Bean 的 Bean 名称为`lambdaFlow.transformer#0`(从版本 5.1 开始),其中使用的是其组件类型,而不是`MethodInvokingTransformer`类的完全限定名称。当必须在流中生成 Bean 名称时,对所有`NamedComponent`s 应用相同的模式。 Bean 这些生成的名称与流 ID 一起前置,以用于诸如解析日志或在某些分析工具中将组件分组在一起的目的,以及在运行时并发注册集成流时避免竞争条件。有关更多信息,请参见[动态和运行时集成流](#java-dsl-runtime-flows)。
### [](#java-dsl-function-expression)`FunctionExpression` ### `FunctionExpression`
我们引入了`FunctionExpression`类(spel 的`Expression`接口的一种实现)来让我们使用 lambdas 和`generics`。当存在来自核心 Spring 集成的隐式`Strategy`变量时,将为 DSL 组件提供`Function<T, R>`选项以及`expression`选项。下面的示例展示了如何使用函数表达式: 我们引入了`FunctionExpression`类(spel 的`Expression`接口的一种实现)来让我们使用 lambdas 和`generics`。当存在来自核心 Spring 集成的隐式`Strategy`变量时,将为 DSL 组件提供`Function<T, R>`选项以及`expression`选项。下面的示例展示了如何使用函数表达式:
...@@ -584,7 +584,7 @@ public IntegrationFlow lambdaFlow() { ...@@ -584,7 +584,7 @@ public IntegrationFlow lambdaFlow() {
`FunctionExpression`还支持运行时类型转换,就像`SpelExpression`中所做的那样。 `FunctionExpression`还支持运行时类型转换,就像`SpelExpression`中所做的那样。
### [](#java-dsl-subflows)子流支持 ### 子流支持
一些`if…​else`和`publish-subscribe`组件提供了通过使用子流指定其逻辑或映射的能力。最简单的示例是`.publishSubscribeChannel()`,如下例所示: 一些`if…​else`和`publish-subscribe`组件提供了通过使用子流指定其逻辑或映射的能力。最简单的示例是`.publishSubscribeChannel()`,如下例所示:
...@@ -664,7 +664,7 @@ public IntegrationFlow routeFlow() { ...@@ -664,7 +664,7 @@ public IntegrationFlow routeFlow() {
| |在 DSL 支持子流配置的情况下,当所配置的组件通常需要一个通道,并且该子流以`channel()`元素开始时,框架会隐式地在组件输出通道和流的输入通道之间放置一个`bridge()`。,例如,在这个`filter`定义中:<br/><br/>```<br/>.filter(p -> p instanceof String, e -> e<br/> .discardFlow(df -> df<br/> .channel(MessageChannels.queue())<br/> ...)<br/>```<br/><br/>框架内部创建了一个`DirectChannel` Bean 用于注入`MessageFilter.discardChannel`。<br/>然后它将子流包装到一个`IntegrationFlow`中,从这个隐式通道开始,用于订阅并在流中指定的`channel()`之前放置一个`bridge`。<br/>当现有的`IntegrationFlow` Bean 被用作子流引用(而不是内置子流,例如 lambda)时,没有这样的桥需要,因为框架可以解析来自第一通道的流 Bean。具有内联子流的输入通道尚不可用。| | |在 DSL 支持子流配置的情况下,当所配置的组件通常需要一个通道,并且该子流以`channel()`元素开始时,框架会隐式地在组件输出通道和流的输入通道之间放置一个`bridge()`。,例如,在这个`filter`定义中:<br/><br/>```<br/>.filter(p -> p instanceof String, e -> e<br/> .discardFlow(df -> df<br/> .channel(MessageChannels.queue())<br/> ...)<br/>```<br/><br/>框架内部创建了一个`DirectChannel` Bean 用于注入`MessageFilter.discardChannel`。<br/>然后它将子流包装到一个`IntegrationFlow`中,从这个隐式通道开始,用于订阅并在流中指定的`channel()`之前放置一个`bridge`。<br/>当现有的`IntegrationFlow` Bean 被用作子流引用(而不是内置子流,例如 lambda)时,没有这样的桥需要,因为框架可以解析来自第一通道的流 Bean。具有内联子流的输入通道尚不可用。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#java-dsl-protocol-adapters)使用协议适配器 ### 使用协议适配器
到目前为止所示的所有示例都说明了 DSL 如何通过使用 Spring 集成编程模型来支持消息传递体系结构。然而,我们还没有进行任何真正的整合。这样做需要通过 HTTP、JMS、AMQP、TCP、JDBC、FTP、SMTP 等访问远程资源,或者访问本地文件系统。 Spring 集成支持所有这些和更多内容。理想情况下,DSL 应该为所有这些功能提供一流的支持,但是实现所有这些功能并随着新的适配器被添加到 Spring 集成中而跟上,这是一项艰巨的任务。因此,期望是 DSL 不断赶上 Spring 集成。 到目前为止所示的所有示例都说明了 DSL 如何通过使用 Spring 集成编程模型来支持消息传递体系结构。然而,我们还没有进行任何真正的整合。这样做需要通过 HTTP、JMS、AMQP、TCP、JDBC、FTP、SMTP 等访问远程资源,或者访问本地文件系统。 Spring 集成支持所有这些和更多内容。理想情况下,DSL 应该为所有这些功能提供一流的支持,但是实现所有这些功能并随着新的适配器被添加到 Spring 集成中而跟上,这是一项艰巨的任务。因此,期望是 DSL 不断赶上 Spring 集成。
...@@ -742,7 +742,7 @@ public AbstractMappingMessageRouter xpathRouter(MessageChannel wrongMessagesChan ...@@ -742,7 +742,7 @@ public AbstractMappingMessageRouter xpathRouter(MessageChannel wrongMessagesChan
} }
``` ```
### [](#java-dsl-flow-adapter)`IntegrationFlowAdapter` ### `IntegrationFlowAdapter`
`IntegrationFlow`接口可以直接实现并指定为用于扫描的组件,如下例所示: `IntegrationFlow`接口可以直接实现并指定为用于扫描的组件,如下例所示:
...@@ -817,7 +817,7 @@ public class MyFlowAdapter extends IntegrationFlowAdapter { ...@@ -817,7 +817,7 @@ public class MyFlowAdapter extends IntegrationFlowAdapter {
} }
``` ```
### [](#java-dsl-runtime-flows)动态和运行时集成流 ### 动态和运行时集成流
`IntegrationFlow`及其所有相关组件都可以在运行时注册。在版本 5.0 之前,我们使用`BeanFactory.registerSingleton()`钩子。从 Spring 框架`5.0`开始,我们使用`instanceSupplier`钩子进行程序化的`BeanDefinition`注册。下面的示例显示了如何以编程方式注册 Bean: `IntegrationFlow`及其所有相关组件都可以在运行时注册。在版本 5.0 之前,我们使用`BeanFactory.registerSingleton()`钩子。从 Spring 框架`5.0`开始,我们使用`instanceSupplier`钩子进行程序化的`BeanDefinition`注册。下面的示例显示了如何以编程方式注册 Bean:
...@@ -923,7 +923,7 @@ private IntegrationFlow buildFlow(int port) { ...@@ -923,7 +923,7 @@ private IntegrationFlow buildFlow(int port) {
| |当你使用`useFlowIdAsPrefix()`时,需要一个`id`属性。| | |当你使用`useFlowIdAsPrefix()`时,需要一个`id`属性。|
|---|-----------------------------------------------------------------| |---|-----------------------------------------------------------------|
### [](#integration-flow-as-gateway)`IntegrationFlow`作为网关 ### `IntegrationFlow`作为网关
`IntegrationFlow`可以从提供`GatewayProxyFactoryBean`组件的服务接口开始,如下例所示: `IntegrationFlow`可以从提供`GatewayProxyFactoryBean`组件的服务接口开始,如下例所示:
...@@ -968,7 +968,7 @@ public IntegrationFlow errorRecovererFlow() { ...@@ -968,7 +968,7 @@ public IntegrationFlow errorRecovererFlow() {
private Function<String, String> errorRecovererFlowGateway; private Function<String, String> errorRecovererFlowGateway;
``` ```
### [](#java-dsl-extensions)DSL 扩展 ### DSL 扩展
从版本 5.3 开始,引入了`IntegrationFlowExtension`,以允许使用自定义或组合的 EIP 操作符扩展现有的 Java DSL。所需要的只是这个类的一个扩展,它提供了可以在`IntegrationFlow` Bean 定义中使用的方法。扩展类还可以用于自定义`IntegrationComponentSpec`配置;例如,可以在现有的`IntegrationComponentSpec`扩展中实现错过的或默认的选项。下面的示例演示了一个复合自定义运算符和`AggregatorSpec`扩展的使用,用于默认的自定义`outputProcessor`: 从版本 5.3 开始,引入了`IntegrationFlowExtension`,以允许使用自定义或组合的 EIP 操作符扩展现有的 Java DSL。所需要的只是这个类的一个扩展,它提供了可以在`IntegrationFlow` Bean 定义中使用的方法。扩展类还可以用于自定义`IntegrationComponentSpec`配置;例如,可以在现有的`IntegrationComponentSpec`扩展中实现错过的或默认的选项。下面的示例演示了一个复合自定义运算符和`AggregatorSpec`扩展的使用,用于默认的自定义`outputProcessor`:
...@@ -1017,7 +1017,7 @@ public IntegrationFlow customFlowDefinition() { ...@@ -1017,7 +1017,7 @@ public IntegrationFlow customFlowDefinition() {
} }
``` ```
### [](#integration-flows-composition)积分流组合 ### 积分流组合
在 Spring 集成中,将`MessageChannel`抽象作为第一类公民,始终假定集成流的组成。流中任何端点的输入通道都可以用于从任何其他端点发送消息,而不仅仅是从具有该通道作为输出的端点发送消息。此外,有了`@MessagingGateway`契约、内容更丰富的组件、像`<chain>`这样的复合端点,以及现在有了`IntegrationFlow`bean(例如`IntegrationFlowAdapter`),在更短的、可重用的部分之间分配业务逻辑就足够简单了。最后一篇作文所需要的只是关于`MessageChannel`发送到或接收到的信息的知识。 在 Spring 集成中,将`MessageChannel`抽象作为第一类公民,始终假定集成流的组成。流中任何端点的输入通道都可以用于从任何其他端点发送消息,而不仅仅是从具有该通道作为输出的端点发送消息。此外,有了`@MessagingGateway`契约、内容更丰富的组件、像`<chain>`这样的复合端点,以及现在有了`IntegrationFlow`bean(例如`IntegrationFlowAdapter`),在更短的、可重用的部分之间分配业务逻辑就足够简单了。最后一篇作文所需要的只是关于`MessageChannel`发送到或接收到的信息的知识。
......
# 集成端点 # 集成端点
## [](#endpoint-summary)端点快速参考表 ## 端点快速参考表
正如前面几节中所讨论的, Spring 集成提供了许多端点,这些端点用于与外部系统、文件系统和其他系统进行接口。 正如前面几节中所讨论的, Spring 集成提供了许多端点,这些端点用于与外部系统、文件系统和其他系统进行接口。
......
# 错误处理 # 错误处理
## [](#error-handling)错误处理 ## 错误处理
正如本手册开头的[overview](./overview.html#overview)中所描述的, Spring 集成之类的面向消息的框架背后的主要动机之一是促进组件之间的松耦合。消息渠道起着重要的作用,因为生产者和消费者不必相互了解。然而,这些优点也有一些缺点。在松散耦合的环境中,有些事情会变得更加复杂,其中一个例子就是错误处理。 正如本手册开头的[overview](./overview.html#overview)中所描述的, Spring 集成之类的面向消息的框架背后的主要动机之一是促进组件之间的松耦合。消息渠道起着重要的作用,因为生产者和消费者不必相互了解。然而,这些优点也有一些缺点。在松散耦合的环境中,有些事情会变得更加复杂,其中一个例子就是错误处理。
......
# Spring 应用事件支持 # Spring 应用事件支持
## [](#applicationevent) Spring `ApplicationEvent`支持 ## Spring `ApplicationEvent`支持
Spring 集成提供了对入站和出站`ApplicationEvents`的支持,如底层 Spring 框架所定义的那样。有关 Spring 对事件和侦听器的支持的更多信息,请参见[Spring Reference Manual](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#context-functionality-events) Spring 集成提供了对入站和出站`ApplicationEvents`的支持,如底层 Spring 框架所定义的那样。有关 Spring 对事件和侦听器的支持的更多信息,请参见[Spring Reference Manual](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#context-functionality-events)
...@@ -22,7 +22,7 @@ Gradle ...@@ -22,7 +22,7 @@ Gradle
compile "org.springframework.integration:spring-integration-event:5.5.9" compile "org.springframework.integration:spring-integration-event:5.5.9"
``` ```
### [](#appevent-inbound)接收 Spring 应用事件 ### 接收 Spring 应用事件
要接收事件并将其发送到通道,你可以定义 Spring Integration 的`ApplicationEventListeningMessageProducer`实例。这个类是 Spring 的`ApplicationListener`接口的实现。默认情况下,它将所有接收到的事件作为 Spring 集成消息传递。要根据事件的类型进行限制,可以使用“eventTypes”属性来配置要接收的事件类型列表。如果接收到的事件有一个`Message`实例作为其“源”,则该`Message`将按原样传递。否则,如果提供了基于 SPEL 的`payloadExpression`,则根据`ApplicationEvent`实例对其进行求值。如果事件的源不是`Message`实例,并且没有提供`payloadExpression`,则`ApplicationEvent`本身将作为有效负载传递。 要接收事件并将其发送到通道,你可以定义 Spring Integration 的`ApplicationEventListeningMessageProducer`实例。这个类是 Spring 的`ApplicationListener`接口的实现。默认情况下,它将所有接收到的事件作为 Spring 集成消息传递。要根据事件的类型进行限制,可以使用“eventTypes”属性来配置要接收的事件类型列表。如果接收到的事件有一个`Message`实例作为其“源”,则该`Message`将按原样传递。否则,如果提供了基于 SPEL 的`payloadExpression`,则根据`ApplicationEvent`实例对其进行求值。如果事件的源不是`Message`实例,并且没有提供`payloadExpression`,则`ApplicationEvent`本身将作为有效负载传递。
...@@ -79,7 +79,7 @@ public IntegrationFlow eventFlow(ApplicationEventListeningMessageProducer events ...@@ -79,7 +79,7 @@ public IntegrationFlow eventFlow(ApplicationEventListeningMessageProducer events
} }
``` ```
### [](#appevent-outbound)发送 Spring 应用程序事件 ### 发送 Spring 应用程序事件
要发送 Spring `ApplicationEvents`,请创建`ApplicationEventPublishingMessageHandler`的一个实例,并将其注册到一个端点中。`MessageHandler`接口的此实现还实现了 Spring 的`ApplicationEventPublisherAware`接口,因此充当 Spring 集成消息和`ApplicationEvents`之间的桥梁。 要发送 Spring `ApplicationEvents`,请创建`ApplicationEventPublishingMessageHandler`的一个实例,并将其注册到一个端点中。`MessageHandler`接口的此实现还实现了 Spring 的`ApplicationEventPublisherAware`接口,因此充当 Spring 集成消息和`ApplicationEvents`之间的桥梁。
......
# 馈源适配器 # 馈源适配器
## [](#feed)提要适配器 ## 提要适配器
Spring 集成通过提要适配器为聚合提供支持。该实现基于[罗马框架](https://rometools.github.io/rome/) Spring 集成通过提要适配器为聚合提供支持。该实现基于[罗马框架](https://rometools.github.io/rome/)
...@@ -32,7 +32,7 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/feed ...@@ -32,7 +32,7 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/feed
https://www.springframework.org/schema/integration/feed/spring-integration-feed.xsd" https://www.springframework.org/schema/integration/feed/spring-integration-feed.xsd"
``` ```
### [](#feed-inbound-channel-adapter)feed 入站通道适配器 ### feed 入站通道适配器
你真正需要为检索提要提供支持的唯一适配器是入站通道适配器。它允许你订阅特定的 URL。下面的示例展示了一种可能的配置: 你真正需要为检索提要提供支持的唯一适配器是入站通道适配器。它允许你订阅特定的 URL。下面的示例展示了一种可能的配置:
...@@ -50,21 +50,21 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/feed ...@@ -50,21 +50,21 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/feed
入站提要通道适配器是一个轮询消费者。这意味着你必须提供一个 Poller 配置。然而,关于提要,你必须了解的一件重要事情是,它的内部工作方式与大多数其他轮询消费者略有不同。启动入站提要适配器时,它执行第一次轮询,并接收`com.sun.syndication.feed.synd.SyndEntryFeed`实例。该对象包含多个`SyndEntry`对象。每个条目存储在本地条目队列中,并基于`max-messages-per-poll`属性中的值释放,这样每个消息都包含一个条目。如果在从条目队列检索条目的过程中,队列已为空,则适配器尝试更新提要,从而在队列中填充更多条目(`SyndEntry`实例)(如果有可用的话)。否则,下一次对提要进行轮询的尝试将由 Poller 的触发器决定(在前面的配置中,每十秒钟进行一次轮询)。 入站提要通道适配器是一个轮询消费者。这意味着你必须提供一个 Poller 配置。然而,关于提要,你必须了解的一件重要事情是,它的内部工作方式与大多数其他轮询消费者略有不同。启动入站提要适配器时,它执行第一次轮询,并接收`com.sun.syndication.feed.synd.SyndEntryFeed`实例。该对象包含多个`SyndEntry`对象。每个条目存储在本地条目队列中,并基于`max-messages-per-poll`属性中的值释放,这样每个消息都包含一个条目。如果在从条目队列检索条目的过程中,队列已为空,则适配器尝试更新提要,从而在队列中填充更多条目(`SyndEntry`实例)(如果有可用的话)。否则,下一次对提要进行轮询的尝试将由 Poller 的触发器决定(在前面的配置中,每十秒钟进行一次轮询)。
### [](#duplicate-entries)重复条目 ### 重复条目
对提要进行轮询可能会导致条目已经被处理(“我已经阅读了该新闻项目,为什么要再次向我显示它?”) Spring 集成提供了一种方便的机制,以消除对重复条目的担心。每个提要条目都有一个“发布日期”字段。每次生成和发送新的`Message`时, Spring 集成都会在`MetadataStore`策略的实例中存储最新发布日期的值(参见[元数据存储](./meta-data-store.html#metadata-store))。 对提要进行轮询可能会导致条目已经被处理(“我已经阅读了该新闻项目,为什么要再次向我显示它?”) Spring 集成提供了一种方便的机制,以消除对重复条目的担心。每个提要条目都有一个“发布日期”字段。每次生成和发送新的`Message`时, Spring 集成都会在`MetadataStore`策略的实例中存储最新发布日期的值(参见[元数据存储](./meta-data-store.html#metadata-store))。
| |用于持久化最新发布日期的键是提要入站通道适配器组件的(必需的)`id`属性的值加上适配器配置中的`feedUrl`(如果有的话)。| | |用于持久化最新发布日期的键是提要入站通道适配器组件的(必需的)`id`属性的值加上适配器配置中的`feedUrl`(如果有的话)。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#other-options)其他选项 ### 其他选项
从版本 5.0 开始,已废弃的`com.rometools.fetcher.FeedFetcher`选项已被删除,并提供了用于`org.springframework.core.io.Resource`的重载`FeedEntryMessageSource`构造函数。当提要源不是 HTTP 端点,而是任何其他资源(例如 FTP 上的本地或远程)时,这很有用。在`FeedEntryMessageSource`逻辑中,这样的资源(或提供`URL`)由`SyndFeedInput`解析到用于前面提到的处理的`SyndFeed`对象。还可以将自定义的`SyndFeedInput`(例如,使用`allowDoctypes`选项)实例注入`FeedEntryMessageSource` 从版本 5.0 开始,已废弃的`com.rometools.fetcher.FeedFetcher`选项已被删除,并提供了用于`org.springframework.core.io.Resource`的重载`FeedEntryMessageSource`构造函数。当提要源不是 HTTP 端点,而是任何其他资源(例如 FTP 上的本地或远程)时,这很有用。在`FeedEntryMessageSource`逻辑中,这样的资源(或提供`URL`)由`SyndFeedInput`解析到用于前面提到的处理的`SyndFeed`对象。还可以将自定义的`SyndFeedInput`(例如,使用`allowDoctypes`选项)实例注入`FeedEntryMessageSource`
| |如果到提要的连接需要一些定制,例如连接和读取超时,则必须使用带有其`customizeConnection(HttpURLConnection)`覆盖功能的`org.springframework.core.io.UrlResource`扩展,而不是普通的`URL`注入到<br/>例如:<br/><br/>```<br/>@Bean<br/>@InboundChannelAdapter("feedChannel")<br/>FeedEntryMessageSource feedEntrySource() {<br/> UrlResource urlResource =<br/> new UrlResource(url) {<br/><br/> @Override<br/> protected void customizeConnection(HttpURLConnection connection) throws IOException {<br/> super.customizeConnection(connection);<br/> connection.setConnectTimeout(10000);<br/> connection.setReadTimeout(5000);<br/> }<br/> };<br/> return new FeedEntryMessageSource(urlResource, "myKey");<br/>}<br/>```| | |如果到提要的连接需要一些定制,例如连接和读取超时,则必须使用带有其`customizeConnection(HttpURLConnection)`覆盖功能的`org.springframework.core.io.UrlResource`扩展,而不是普通的`URL`注入到<br/>例如:<br/><br/>```<br/>@Bean<br/>@InboundChannelAdapter("feedChannel")<br/>FeedEntryMessageSource feedEntrySource() {<br/> UrlResource urlResource =<br/> new UrlResource(url) {<br/><br/> @Override<br/> protected void customizeConnection(HttpURLConnection connection) throws IOException {<br/> super.customizeConnection(connection);<br/> connection.setConnectTimeout(10000);<br/> connection.setReadTimeout(5000);<br/> }<br/> };<br/> return new FeedEntryMessageSource(urlResource, "myKey");<br/>}<br/>```|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#feed-java-configuration)Java DSL 配置 ### Java DSL 配置
下面的 Spring 引导应用程序展示了如何使用 Java DSL 配置入站适配器的示例: 下面的 Spring 引导应用程序展示了如何使用 Java DSL 配置入站适配器的示例:
......
此差异已折叠。
此差异已折叠。
# Pivotal Gemfire 和 Apache Geode 支持 # Pivotal Gemfire 和 Apache Geode 支持
## [](#gemfire)Pivotal Gemfire 和 Apache Geode 支持 ## Pivotal Gemfire 和 Apache Geode 支持
Spring 集成为 Pivotal Gemfire 和 Apache Geode 提供了支持。 Spring 集成为 Pivotal Gemfire 和 Apache Geode 提供了支持。
...@@ -54,7 +54,7 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/gemfire ...@@ -54,7 +54,7 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/gemfire
https://www.springframework.org/schema/integration/gemfire/spring-integration-gemfire.xsd" https://www.springframework.org/schema/integration/gemfire/spring-integration-gemfire.xsd"
``` ```
### [](#gemfire-inbound)入站通道适配器 ### 入站通道适配器
当 Gemfire`EntryEvent`触发时,入站通道适配器在通道上生成消息。每当相关区域中的条目`CREATED``UPDATED``DESTROYED``INVALIDATED`时,Gemfire 都会生成事件。入站通道适配器允许你筛选这些事件的一个子集。例如,你可能希望仅在响应正在创建的条目时生成消息。此外,如果希望消息有效负载包含事件属性(如新的 entry 值),则入站通道适配器可以计算 SPEL 表达式。下面的示例展示了如何使用 SPEL 语言(在`expression`属性中)配置入站通道适配器: 当 Gemfire`EntryEvent`触发时,入站通道适配器在通道上生成消息。每当相关区域中的条目`CREATED``UPDATED``DESTROYED``INVALIDATED`时,Gemfire 都会生成事件。入站通道适配器允许你筛选这些事件的一个子集。例如,你可能希望仅在响应正在创建的条目时生成消息。此外,如果希望消息有效负载包含事件属性(如新的 entry 值),则入站通道适配器可以计算 SPEL 表达式。下面的示例展示了如何使用 SPEL 语言(在`expression`属性中)配置入站通道适配器:
...@@ -76,7 +76,7 @@ expression="new something.MyEvent(key, oldValue, newValue)" ...@@ -76,7 +76,7 @@ expression="new something.MyEvent(key, oldValue, newValue)"
| |此适配器符合 Spring 集成约定。| | |此适配器符合 Spring 集成约定。|
|---|--------------------------------------------------------| |---|--------------------------------------------------------|
### [](#gemfire-cq)连续查询入站通道适配器 ### 连续查询入站通道适配器
当 Gemfire 连续查询或`CqEvent`事件触发时,连续查询入站通道适配器在通道上生成消息。在版本`1.1`中, Spring Data 引入了连续查询支持,包括`ContinuousQueryListenerContainer`,这在 Gemfire 原生 API 上提供了一个很好的抽象。这个适配器需要对`ContinuousQueryListenerContainer`实例的引用,为给定的`query`创建一个侦听器,并执行查询。连续查询充当事件源,每当其结果集更改状态时,它都会触发事件源。 当 Gemfire 连续查询或`CqEvent`事件触发时,连续查询入站通道适配器在通道上生成消息。在版本`1.1`中, Spring Data 引入了连续查询支持,包括`ContinuousQueryListenerContainer`,这在 Gemfire 原生 API 上提供了一个很好的抽象。这个适配器需要对`ContinuousQueryListenerContainer`实例的引用,为给定的`query`创建一个侦听器,并执行查询。连续查询充当事件源,每当其结果集更改状态时,它都会触发事件源。
...@@ -107,7 +107,7 @@ expression="new something.MyEvent(key, oldValue, newValue)" ...@@ -107,7 +107,7 @@ expression="new something.MyEvent(key, oldValue, newValue)"
| |此适配器符合 Spring 集成约定。| | |此适配器符合 Spring 集成约定。|
|---|--------------------------------------------------------| |---|--------------------------------------------------------|
### [](#gemfire-outbound)出站通道适配器 ### 出站通道适配器
出站通道适配器写入从消息有效负载映射的缓存项。在其最简单的形式中,它期望类型`java.util.Map`的有效负载,并将映射条目放入其配置的区域中。下面的示例展示了如何配置出站通道适配器: 出站通道适配器写入从消息有效负载映射的缓存项。在其最简单的形式中,它期望类型`java.util.Map`的有效负载,并将映射条目放入其配置的区域中。下面的示例展示了如何配置出站通道适配器:
...@@ -128,7 +128,7 @@ expression="new something.MyEvent(key, oldValue, newValue)" ...@@ -128,7 +128,7 @@ expression="new something.MyEvent(key, oldValue, newValue)"
在前面的配置中,内部元素(`cache-entries`)在语义上等同于 Spring’map’元素。适配器将`key``value`属性解释为 SPEL 表达式,并将消息作为求值上下文。请注意,这可以包含任意的缓存条目(不仅仅是从消息派生的条目),并且文字值必须用单引号括起来。在前面的示例中,如果发送到`cacheChannel`的消息具有`String``Hello`的有效负载,则在缓存区域中写入两个条目(`[HELLO:hello, thing1:thing2]`)(要么创建要么更新)。此适配器还支持`order`属性,如果将其绑定到`PublishSubscribeChannel`,则该属性可能很有用。 在前面的配置中,内部元素(`cache-entries`)在语义上等同于 Spring’map’元素。适配器将`key``value`属性解释为 SPEL 表达式,并将消息作为求值上下文。请注意,这可以包含任意的缓存条目(不仅仅是从消息派生的条目),并且文字值必须用单引号括起来。在前面的示例中,如果发送到`cacheChannel`的消息具有`String``Hello`的有效负载,则在缓存区域中写入两个条目(`[HELLO:hello, thing1:thing2]`)(要么创建要么更新)。此适配器还支持`order`属性,如果将其绑定到`PublishSubscribeChannel`,则该属性可能很有用。
### [](#gemfire-message-store)Gemfire 消息存储 ### Gemfire 消息存储
正如 EIP 中所描述的,[消息存储](https://www.enterpriseintegrationpatterns.com/MessageStore.html)允许你持久化消息。在处理具有缓冲消息能力的组件(`QueueChannel``Aggregator``Resequencer`,以及其他)时,如果可靠性是一个问题,这可能是有用的。在 Spring 集成中,`MessageStore`策略接口还为[索赔检查](https://www.enterpriseintegrationpatterns.com/StoreInLibrary.html)模式提供了基础,这也在 EIP 中进行了描述。 正如 EIP 中所描述的,[消息存储](https://www.enterpriseintegrationpatterns.com/MessageStore.html)允许你持久化消息。在处理具有缓冲消息能力的组件(`QueueChannel``Aggregator``Resequencer`,以及其他)时,如果可靠性是一个问题,这可能是有用的。在 Spring 集成中,`MessageStore`策略接口还为[索赔检查](https://www.enterpriseintegrationpatterns.com/StoreInLibrary.html)模式提供了基础,这也在 EIP 中进行了描述。
...@@ -174,14 +174,14 @@ Spring Integration 的 Gemfire 模块提供了`GemfireMessageStore`,这是`Mes ...@@ -174,14 +174,14 @@ Spring Integration 的 Gemfire 模块提供了`GemfireMessageStore`,这是`Mes
从版本 4.3.12 开始,`GemfireMessageStore`支持键`prefix`选项,以允许在同一 Gemfire 区域上的存储实例之间进行区分。 从版本 4.3.12 开始,`GemfireMessageStore`支持键`prefix`选项,以允许在同一 Gemfire 区域上的存储实例之间进行区分。
### [](#gemfire-lock-registry)Gemfire Lock 注册表 ### Gemfire Lock 注册表
从版本 4.0 开始,`GemfireLockRegistry`是可用的。某些组件(例如,聚合器和重排序程序)使用从`LockRegistry`实例获得的锁,以确保在任何给定的时间只有一个线程正在操作组。`DefaultLockRegistry`在单个组件中执行此功能。现在,你可以在这些组件上配置一个外部锁注册中心。当你使用与`GemfireLockRegistry`共享的`MessageGroupStore`时,它可以跨多个应用程序实例提供此功能,从而一次只有一个实例可以操作组。 从版本 4.0 开始,`GemfireLockRegistry`是可用的。某些组件(例如,聚合器和重排序程序)使用从`LockRegistry`实例获得的锁,以确保在任何给定的时间只有一个线程正在操作组。`DefaultLockRegistry`在单个组件中执行此功能。现在,你可以在这些组件上配置一个外部锁注册中心。当你使用与`GemfireLockRegistry`共享的`MessageGroupStore`时,它可以跨多个应用程序实例提供此功能,从而一次只有一个实例可以操作组。
| |其中一个`GemfireLockRegistry`构造函数需要一个`Region`作为参数。<br/>它用于从`getDistributedLock()`方法获得一个`Lock`<br/>该操作需要`GLOBAL`用于`Region`的作用域。,<br/>另一个构造函数需要一个`Cache`,而`Region`是用`GLOBAL`作用域和名称`LockRegistry`创建的。| | |其中一个`GemfireLockRegistry`构造函数需要一个`Region`作为参数。<br/>它用于从`getDistributedLock()`方法获得一个`Lock`<br/>该操作需要`GLOBAL`用于`Region`的作用域。,<br/>另一个构造函数需要一个`Cache`,而`Region`是用`GLOBAL`作用域和名称`LockRegistry`创建的。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#gemfire-metadata-store)Gemfire 元数据存储 ### Gemfire 元数据存储
4.0 版本引入了一个新的基于 Gemfire 的`MetadataStore`[元数据存储](./meta-data-store.html#metadata-store))实现。你可以使用`GemfireMetadataStore`在应用程序重新启动期间维护元数据状态。这个新的`MetadataStore`实现可以与适配器一起使用,例如: 4.0 版本引入了一个新的基于 Gemfire 的`MetadataStore`[元数据存储](./meta-data-store.html#metadata-store))实现。你可以使用`GemfireMetadataStore`在应用程序重新启动期间维护元数据状态。这个新的`MetadataStore`实现可以与适配器一起使用,例如:
......
此差异已折叠。
# HTTP 支持 # HTTP 支持
## [](#http)http 支持 ## http 支持
Spring 集成的 HTTP 支持允许运行 HTTP 请求和处理入站 HTTP 请求。HTTP 支持由以下网关实现组成:`HttpInboundEndpoint``HttpRequestExecutingMessageHandler`。另见[WebFlux 支持](./webflux.html#webflux) Spring 集成的 HTTP 支持允许运行 HTTP 请求和处理入站 HTTP 请求。HTTP 支持由以下网关实现组成:`HttpInboundEndpoint``HttpRequestExecutingMessageHandler`。另见[WebFlux 支持](./webflux.html#webflux)
...@@ -24,7 +24,7 @@ compile "org.springframework.integration:spring-integration-http:5.5.9" ...@@ -24,7 +24,7 @@ compile "org.springframework.integration:spring-integration-http:5.5.9"
必须在目标 Servlet 容器上提供`javax.servlet:javax.servlet-api`依赖项。 必须在目标 Servlet 容器上提供`javax.servlet:javax.servlet-api`依赖项。
### [](#http-inbound)HTTP 入站组件 ### HTTP 入站组件
要通过 HTTP 接收消息,需要使用 HTTP 入站通道适配器或 HTTP 入站网关。为了支持 HTTP 入站适配器,它们需要部署在 Servlet 容器中,例如[Apache Tomcat](https://tomcat.apache.org/)[Jetty](https://www.eclipse.org/jetty/)。最简单的方法是使用 Spring 的[`HttpRequestHandlerServlet`](https://DOCS. Spring.io/ Spring/DOCS/current/javadoc-api/org/springframework/web/context/support/httprequesthandlerservlet.html),在`web.xml`文件中提供以下 Servlet 定义: 要通过 HTTP 接收消息,需要使用 HTTP 入站通道适配器或 HTTP 入站网关。为了支持 HTTP 入站适配器,它们需要部署在 Servlet 容器中,例如[Apache Tomcat](https://tomcat.apache.org/)[Jetty](https://www.eclipse.org/jetty/)。最简单的方法是使用 Spring 的[`HttpRequestHandlerServlet`](https://DOCS. Spring.io/ Spring/DOCS/current/javadoc-api/org/springframework/web/context/support/httprequesthandlerservlet.html),在`web.xml`文件中提供以下 Servlet 定义:
...@@ -86,15 +86,15 @@ Spring 集成 2.0 实现了对多部分文件的支持。如果请求被包装 ...@@ -86,15 +86,15 @@ Spring 集成 2.0 实现了对多部分文件的支持。如果请求被包装
回复消息可在模型图中获得。默认情况下,该映射条目的键是“replyKey”,但是你可以通过在端点的配置上设置“replyKey”属性来覆盖此缺省项。 回复消息可在模型图中获得。默认情况下,该映射条目的键是“replyKey”,但是你可以通过在端点的配置上设置“replyKey”属性来覆盖此缺省项。
#### [](#http-validation)有效载荷验证 #### 有效载荷验证
从版本 5.2 开始,HTTP 入站端点可以提供`Validator`,以在发送到通道之前检查有效负载。这个有效负载已经是`payloadExpression`之后的转换和提取的结果,以缩小关于有价值数据的验证范围。验证失败处理与 Spring MVC[错误处理](https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-exceptionhandlers)中的处理完全相同。 从版本 5.2 开始,HTTP 入站端点可以提供`Validator`,以在发送到通道之前检查有效负载。这个有效负载已经是`payloadExpression`之后的转换和提取的结果,以缩小关于有价值数据的验证范围。验证失败处理与 Spring MVC[错误处理](https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-exceptionhandlers)中的处理完全相同。
### [](#http-outbound)HTTP 出站组件 ### HTTP 出站组件
本节描述 Spring 集成的 HTTP 出站组件。 本节描述 Spring 集成的 HTTP 出站组件。
#### [](#using-httprequestexecutingmessagehandler)使用`HttpRequestExecutingMessageHandler` #### 使用`HttpRequestExecutingMessageHandler`
要配置`HttpRequestExecutingMessageHandler`,请编写一个 Bean 定义,类似于以下内容: 要配置`HttpRequestExecutingMessageHandler`,请编写一个 Bean 定义,类似于以下内容:
...@@ -123,7 +123,7 @@ Bean 这个定义通过将 HTTP 请求委托给`RestTemplate`来运行。然后 ...@@ -123,7 +123,7 @@ Bean 这个定义通过将 HTTP 请求委托给`RestTemplate`来运行。然后
| |对于出站网关,网关产生的回复消息包含请求消息中存在的所有消息头。| | |对于出站网关,网关产生的回复消息包含请求消息中存在的所有消息头。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------| |---|---------------------------------------------------------------------------------------------------------------------------------------------|
#### [](#using-cookies)使用 cookies #### 使用 cookies
出站网关上的`transfer-cookies`属性提供了基本的 cookie 支持。当设置为`true`(默认值为`false`)时,从服务器接收到的响应中的`Set-Cookie`头将在回复消息中转换为`Cookie`。然后在后续的发送中使用这个头。这使得能够进行简单的有状态交互,例如: 出站网关上的`transfer-cookies`属性提供了基本的 cookie 支持。当设置为`true`(默认值为`false`)时,从服务器接收到的响应中的`Set-Cookie`头将在回复消息中转换为`Cookie`。然后在后续的发送中使用这个头。这使得能够进行简单的有状态交互,例如:
...@@ -139,7 +139,7 @@ Bean 这个定义通过将 HTTP 请求委托给`RestTemplate`来运行。然后 ...@@ -139,7 +139,7 @@ Bean 这个定义通过将 HTTP 请求委托给`RestTemplate`来运行。然后
从版本 5.5 开始,`HttpRequestExecutingMessageHandler`公开了一个`extractResponseBody`标志(默认情况下是`true`),以仅返回响应主体,或返回整个`ResponseEntity`作为回复消息的有效负载,独立于所提供的`expectedResponseType`。如果`ResponseEntity`中不存在主体,则忽略此标志,并返回整个`ResponseEntity` 从版本 5.5 开始,`HttpRequestExecutingMessageHandler`公开了一个`extractResponseBody`标志(默认情况下是`true`),以仅返回响应主体,或返回整个`ResponseEntity`作为回复消息的有效负载,独立于所提供的`expectedResponseType`。如果`ResponseEntity`中不存在主体,则忽略此标志,并返回整个`ResponseEntity`
### [](#http-namespace)http 名称空间支持 ### http 名称空间支持
Spring 集成提供了`http`名称空间和相应的模式定义。要将其包含在配置中,请在应用程序上下文配置文件中提供以下名称空间声明: Spring 集成提供了`http`名称空间和相应的模式定义。要将其包含在配置中,请在应用程序上下文配置文件中提供以下名称空间声明:
...@@ -160,7 +160,7 @@ Spring 集成提供了`http`名称空间和相应的模式定义。要将其包 ...@@ -160,7 +160,7 @@ Spring 集成提供了`http`名称空间和相应的模式定义。要将其包
</beans> </beans>
``` ```
#### [](#inbound)入站 #### 入站
XML 命名空间为处理 HTTP 入站请求提供了两个组件:`inbound-channel-adapter``inbound-gateway`。为了在不返回专用响应的情况下处理请求,请使用`inbound-channel-adapter`。下面的示例展示了如何配置一个: XML 命名空间为处理 HTTP 入站请求提供了两个组件:`inbound-channel-adapter``inbound-gateway`。为了在不返回专用响应的情况下处理请求,请使用`inbound-channel-adapter`。下面的示例展示了如何配置一个:
...@@ -177,7 +177,7 @@ XML 命名空间为处理 HTTP 入站请求提供了两个组件:`inbound-chan ...@@ -177,7 +177,7 @@ XML 命名空间为处理 HTTP 入站请求提供了两个组件:`inbound-chan
reply-channel="responses"/> reply-channel="responses"/>
``` ```
#### [](#http-request-mapping)请求映射支持 #### 请求映射支持
| |Spring Integration3.0 通过引入[](https://DOCS. Spring.io/ Spring-Integration/API/org/SpringFramework/Integration/HTTP/Inbound/IntegrationRequestMappinghandlerMapping.html)改进了 REST 支持。实现依赖于 Spring Framework3.1 或更高版本提供的增强型 REST 支持。| | |Spring Integration3.0 通过引入[](https://DOCS. Spring.io/ Spring-Integration/API/org/SpringFramework/Integration/HTTP/Inbound/IntegrationRequestMappinghandlerMapping.html)改进了 REST 支持。实现依赖于 Spring Framework3.1 或更高版本提供的增强型 REST 支持。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
...@@ -243,7 +243,7 @@ HTTP 入站网关或 HTTP 入站通道适配器的解析注册了类型为[`inte ...@@ -243,7 +243,7 @@ HTTP 入站网关或 HTTP 入站通道适配器的解析注册了类型为[`inte
| |`IntegrationRequestMappingHandlerMapping`扩展了 Spring MVC`RequestMappingHandlerMapping`类,继承了它的大部分逻辑,尤其是`handleNoMatch(Set, String, HttpServletRequest)`,当映射由于某种原因不匹配时,它会为 HTTP 响应抛出一个特定的`4xx`错误,防止调用应用程序上下文中的任何剩余映射处理程序。<br/>因此,为 Spring 集成和 Spring MVC 请求映射(例如,不支持`POST`in one 和`GET`in the other);将找不到 MVC 映射。| | |`IntegrationRequestMappingHandlerMapping`扩展了 Spring MVC`RequestMappingHandlerMapping`类,继承了它的大部分逻辑,尤其是`handleNoMatch(Set, String, HttpServletRequest)`,当映射由于某种原因不匹配时,它会为 HTTP 响应抛出一个特定的`4xx`错误,防止调用应用程序上下文中的任何剩余映射处理程序。<br/>因此,为 Spring 集成和 Spring MVC 请求映射(例如,不支持`POST`in one 和`GET`in the other);将找不到 MVC 映射。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### [](#http-cors)跨源资源共享支持 #### 跨源资源共享支持
从版本 4.2 开始,你可以使用`<cross-origin>`元素配置`<http:inbound-channel-adapter>``<http:inbound-gateway>`。它表示与 Spring MVC 的`@CrossOrigin`用于`@Controller`注释的选项相同的选项,并允许为 Spring 集成 HTTP 端点配置跨源资源共享: 从版本 4.2 开始,你可以使用`<cross-origin>`元素配置`<http:inbound-channel-adapter>``<http:inbound-gateway>`。它表示与 Spring MVC 的`@CrossOrigin`用于`@Controller`注释的选项相同的选项,并允许为 Spring 集成 HTTP 端点配置跨源资源共享:
...@@ -261,7 +261,7 @@ HTTP 入站网关或 HTTP 入站通道适配器的解析注册了类型为[`inte ...@@ -261,7 +261,7 @@ HTTP 入站网关或 HTTP 入站通道适配器的解析注册了类型为[`inte
CORS Java 配置由`org.springframework.integration.http.inbound.CrossOrigin`类表示,其实例可以注入到`HttpRequestHandlingEndpointSupport`bean 中。 CORS Java 配置由`org.springframework.integration.http.inbound.CrossOrigin`类表示,其实例可以注入到`HttpRequestHandlingEndpointSupport`bean 中。
#### [](#http-response-statuscode)响应状态代码 #### 响应状态代码
从版本 4.1 开始,你可以将`<http:inbound-channel-adapter>`配置为`status-code-expression`,以覆盖默认的`200 OK`状态。表达式必须返回一个可以转换为`org.springframework.http.HttpStatus`enum 值的对象。`evaluationContext`具有`BeanResolver`,并且从版本 5.1 开始,提供了作为根对象的`RequestEntity<?>`。一个例子可能是在运行时解析某个范围 Bean,该范围返回一个状态代码值。然而,最有可能的是,它被设置为固定值,如`status-code=expression="204"`(没有内容),或`status-code-expression="T(org.springframework.http.HttpStatus).NO_CONTENT"`。默认情况下,`status-code-expression`为 null,这意味着返回正常的’200OK’响应状态。使用`RequestEntity<?>`作为根对象,状态码可以是有条件的,例如在请求方法、一些头、URI 内容甚至请求体上。下面的示例展示了如何将状态代码设置为`ACCEPTED`: 从版本 4.1 开始,你可以将`<http:inbound-channel-adapter>`配置为`status-code-expression`,以覆盖默认的`200 OK`状态。表达式必须返回一个可以转换为`org.springframework.http.HttpStatus`enum 值的对象。`evaluationContext`具有`BeanResolver`,并且从版本 5.1 开始,提供了作为根对象的`RequestEntity<?>`。一个例子可能是在运行时解析某个范围 Bean,该范围返回一个状态代码值。然而,最有可能的是,它被设置为固定值,如`status-code=expression="204"`(没有内容),或`status-code-expression="T(org.springframework.http.HttpStatus).NO_CONTENT"`。默认情况下,`status-code-expression`为 null,这意味着返回正常的’200OK’响应状态。使用`RequestEntity<?>`作为根对象,状态码可以是有条件的,例如在请求方法、一些头、URI 内容甚至请求体上。下面的示例展示了如何将状态代码设置为`ACCEPTED`:
...@@ -340,7 +340,7 @@ Spring Integration3.0 之后,除了现有的`#pathVariables`和`#requestParams ...@@ -340,7 +340,7 @@ Spring Integration3.0 之后,除了现有的`#pathVariables`和`#requestParams
requestAttributes.request.queryString"/> requestAttributes.request.queryString"/>
``` ```
#### [](#outbound)出站 #### 出站
要配置出站网关,你可以使用名称空间支持。以下代码片段显示了出站 HTTP 网关的可用配置选项: 要配置出站网关,你可以使用名称空间支持。以下代码片段显示了出站 HTTP 网关的可用配置选项:
...@@ -398,7 +398,7 @@ Spring Integration3.0 之后,除了现有的`#pathVariables`和`#requestParams ...@@ -398,7 +398,7 @@ Spring Integration3.0 之后,除了现有的`#pathVariables`和`#requestParams
| |要指定 URL,可以使用“url”属性或“url-expression”属性。<br/>“url”属性接受一个简单的字符串(对于 URI 变量有占位符,如下所述)。<br/>“url-expression”是一个 SPEL 表达式,以`Message`作为根对象,<br/>表达式求值结果的 URL 仍然可以有 URI 变量的占位符。<br/><br/>在以前的版本中,一些用户使用占位符用 URI 变量替换整个 URL,<br/> Spring 3.1 中的更改可能会导致转义字符的一些问题,例如“?”。<br/>出于这个原因,我们建议,如果你希望在运行时完全生成 URL,那么可以使用“url-expression”属性。| | |要指定 URL,可以使用“url”属性或“url-expression”属性。<br/>“url”属性接受一个简单的字符串(对于 URI 变量有占位符,如下所述)。<br/>“url-expression”是一个 SPEL 表达式,以`Message`作为根对象,<br/>表达式求值结果的 URL 仍然可以有 URI 变量的占位符。<br/><br/>在以前的版本中,一些用户使用占位符用 URI 变量替换整个 URL,<br/> Spring 3.1 中的更改可能会导致转义字符的一些问题,例如“?”。<br/>出于这个原因,我们建议,如果你希望在运行时完全生成 URL,那么可以使用“url-expression”属性。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### [](#mapping-uri-variables)映射 URI 变量 #### 映射 URI 变量
如果你的 URL 包含 URI 变量,那么你可以使用`uri-variable`元素来映射它们。此元素可用于 HTTP 出站网关和 HTTP 出站通道适配器。下面的示例将`zipCode`URI 变量映射到一个表达式: 如果你的 URL 包含 URI 变量,那么你可以使用`uri-variable`元素来映射它们。此元素可用于 HTTP 出站网关和 HTTP 出站通道适配器。下面的示例将`zipCode`URI 变量映射到一个表达式:
...@@ -486,7 +486,7 @@ List<NameValuePair> nameValuePairs = ...@@ -486,7 +486,7 @@ List<NameValuePair> nameValuePairs =
.collect(Collectors.toList()); .collect(Collectors.toList());
``` ```
#### [](#http-uri-encoding)控制 URI 编码 #### 控制 URI 编码
默认情况下,URL 字符串在发送请求之前被编码(参见[`UriComponentsBuilder`](https://DOCS. Spring.io/ Spring/DOCS/current/javadoc-api/org/springframework/web/util/uricomponentsbuilder.html))到 URI 对象。在使用非标准 URI(例如 RabbitMQ REST API)的某些场景中,不希望执行编码。`<http:outbound-gateway/>``<http:outbound-channel-adapter/>`提供了一个`encoding-mode`属性。要禁用对 URL 进行编码,请将此属性设置为`NONE`(默认情况下,它是`TEMPLATE_AND_VALUES`)。如果希望对某些 URL 进行部分编码,请在`<uri-variable/>`中使用`expression`,如下例所示: 默认情况下,URL 字符串在发送请求之前被编码(参见[`UriComponentsBuilder`](https://DOCS. Spring.io/ Spring/DOCS/current/javadoc-api/org/springframework/web/util/uricomponentsbuilder.html))到 URI 对象。在使用非标准 URI(例如 RabbitMQ REST API)的某些场景中,不希望执行编码。`<http:outbound-gateway/>``<http:outbound-channel-adapter/>`提供了一个`encoding-mode`属性。要禁用对 URL 进行编码,请将此属性设置为`NONE`(默认情况下,它是`TEMPLATE_AND_VALUES`)。如果希望对某些 URL 进行部分编码,请在`<uri-variable/>`中使用`expression`,如下例所示:
...@@ -500,7 +500,7 @@ List<NameValuePair> nameValuePairs = ...@@ -500,7 +500,7 @@ List<NameValuePair> nameValuePairs =
使用 Java DSL,这个选项可以由`BaseHttpMessageHandlerSpec.encodingMode()`选项控制。相同的配置适用于[WebFlux 模块](./webflux.html#webflux)[Web 服务模块](./ws.html#ws)中的类似出站组件。对于非常复杂的场景,建议在外部提供的`RestTemplate`上配置`UriTemplateHandler`;或者在 WebFlux-`WebClient`的情况下配置`UriBuilderFactory` 使用 Java DSL,这个选项可以由`BaseHttpMessageHandlerSpec.encodingMode()`选项控制。相同的配置适用于[WebFlux 模块](./webflux.html#webflux)[Web 服务模块](./ws.html#ws)中的类似出站组件。对于非常复杂的场景,建议在外部提供的`RestTemplate`上配置`UriTemplateHandler`;或者在 WebFlux-`WebClient`的情况下配置`UriBuilderFactory`
### [](#http-java-config)用 Java 配置 HTTP 端点 ### 用 Java 配置 HTTP 端点
下面的示例展示了如何使用 Java 配置入站网关: 下面的示例展示了如何使用 Java 配置入站网关:
...@@ -572,7 +572,7 @@ public IntegrationFlow outbound() { ...@@ -572,7 +572,7 @@ public IntegrationFlow outbound() {
} }
``` ```
### [](#http-timeout)超时处理 ### 超时处理
在 HTTP 组件的上下文中,必须考虑两个计时区域: 在 HTTP 组件的上下文中,必须考虑两个计时区域:
...@@ -633,7 +633,7 @@ public IntegrationFlow outbound() { ...@@ -633,7 +633,7 @@ public IntegrationFlow outbound() {
*发送超时*属性的值默认为“-1”,并将应用于连接的`MessageChannel`。这意味着,根据实现方式,消息通道的*发送*方法可能无限期地阻塞。此外,*发送超时*属性仅在实际的 MessageChannel 实现具有阻塞发送(例如’full’bounded queuechannel)时使用。 *发送超时*属性的值默认为“-1”,并将应用于连接的`MessageChannel`。这意味着,根据实现方式,消息通道的*发送*方法可能无限期地阻塞。此外,*发送超时*属性仅在实际的 MessageChannel 实现具有阻塞发送(例如’full’bounded queuechannel)时使用。
#### [](#http-inbound-gateway)HTTP 入站网关 #### HTTP 入站网关
对于 HTTP 入站网关,XML 模式定义了`request-timeout`属性,该属性用于在`HttpRequestHandlingMessagingGateway`类上(在扩展的`MessagingGatewaySupport`类上)设置`requestTimeout`属性。你还可以使用`reply-timeout`属性映射到同一个类上的`replyTimeout`属性。 对于 HTTP 入站网关,XML 模式定义了`request-timeout`属性,该属性用于在`HttpRequestHandlingMessagingGateway`类上(在扩展的`MessagingGatewaySupport`类上)设置`requestTimeout`属性。你还可以使用`reply-timeout`属性映射到同一个类上的`replyTimeout`属性。
...@@ -642,11 +642,11 @@ public IntegrationFlow outbound() { ...@@ -642,11 +642,11 @@ public IntegrationFlow outbound() {
| |要模拟连接超时,可以连接到不可路由的 IP 地址,例如 10.255.255.10。| | |要模拟连接超时,可以连接到不可路由的 IP 地址,例如 10.255.255.10。|
|---|-----------------------------------------------------------------------------------------------------| |---|-----------------------------------------------------------------------------------------------------|
### [](#http-proxy)HTTP 代理配置 ### HTTP 代理配置
如果你支持代理,并且需要为 HTTP 出站适配器或网关配置代理设置,那么可以应用以下两种方法中的一种。在大多数情况下,你可以依赖控制代理设置的标准 Java 系统属性。否则,你可以为 HTTP 客户机请求工厂实例显式配置一个 Spring Bean。 如果你支持代理,并且需要为 HTTP 出站适配器或网关配置代理设置,那么可以应用以下两种方法中的一种。在大多数情况下,你可以依赖控制代理设置的标准 Java 系统属性。否则,你可以为 HTTP 客户机请求工厂实例显式配置一个 Spring Bean。
#### [](#standard-java-proxy-configuration)标准 Java 代理配置 #### 标准 Java 代理配置
你可以设置三个系统属性来配置 HTTP 协议处理程序使用的代理设置: 你可以设置三个系统属性来配置 HTTP 协议处理程序使用的代理设置:
...@@ -664,7 +664,7 @@ public IntegrationFlow outbound() { ...@@ -664,7 +664,7 @@ public IntegrationFlow outbound() {
有关更多信息,请参见[https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html](https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html) 有关更多信息,请参见[https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html](https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html)
#### [](#springs-simpleclienthttprequestfactory) Spring 的`SimpleClientHttpRequestFactory` #### Spring 的`SimpleClientHttpRequestFactory`
如果需要对代理配置进行更明确的控制,可以使用 Spring 的`SimpleClientHttpRequestFactory`并配置其’代理’属性,如下例所示: 如果需要对代理配置进行更明确的控制,可以使用 Spring 的`SimpleClientHttpRequestFactory`并配置其’代理’属性,如下例所示:
...@@ -687,7 +687,7 @@ public IntegrationFlow outbound() { ...@@ -687,7 +687,7 @@ public IntegrationFlow outbound() {
</bean> </bean>
``` ```
### [](#http-header-mapping)HTTP 标头映射 ### HTTP 标头映射
Spring 集成为 HTTP 请求和 HTTP 响应提供了对 HTTP 头映射的支持。 Spring 集成为 HTTP 请求和 HTTP 响应提供了对 HTTP 头映射的支持。
...@@ -726,15 +726,15 @@ Spring 集成为 HTTP 请求和 HTTP 响应提供了对 HTTP 头映射的支持 ...@@ -726,15 +726,15 @@ Spring 集成为 HTTP 请求和 HTTP 响应提供了对 HTTP 头映射的支持
如果你需要执行`DefaultHttpHeaderMapper`所支持的以外的操作,则可以直接实现`HeaderMapper`策略接口,并提供对你的实现的引用。 如果你需要执行`DefaultHttpHeaderMapper`所支持的以外的操作,则可以直接实现`HeaderMapper`策略接口,并提供对你的实现的引用。
### [](#int-graph-controller)积分图控制器 ### 积分图控制器
从版本 4.3 开始,HTTP 模块提供了`@EnableIntegrationGraphController`配置类注释和`<int-http:graph-controller/>`XML 元素,以将`IntegrationGraphServer`作为 REST 服务公开。有关更多信息,请参见[积分图](./graph.html#integration-graph) 从版本 4.3 开始,HTTP 模块提供了`@EnableIntegrationGraphController`配置类注释和`<int-http:graph-controller/>`XML 元素,以将`IntegrationGraphServer`作为 REST 服务公开。有关更多信息,请参见[积分图](./graph.html#integration-graph)
### [](#http-samples)http 样本 ### http 样本
本节用几个例子来概括我们对 Spring Integration 的 HTTP 支持的介绍。 本节用几个例子来概括我们对 Spring Integration 的 HTTP 支持的介绍。
#### [](#multipart-rest-inbound)多部分 HTTP 请求—RESTTemplate(客户端)和 HTTP 入站网关(服务器) #### 多部分 HTTP 请求—RESTTemplate(客户端)和 HTTP 入站网关(服务器)
这个示例展示了用 Spring 的`RestTemplate`发送多部分 HTTP 请求并用 Spring 集成 HTTP 入站适配器接收它是多么简单。我们创建`MultiValueMap`并用多部分数据填充它。`RestTemplate`通过将其转换为`MultipartHttpServletRequest`来处理其余部分(没有双关语)。这个特定的客户机发送一个包含公司名称和一个图像文件(公司标识)的多部分 HTTP 请求。下面的清单展示了这个示例: 这个示例展示了用 Spring 的`RestTemplate`发送多部分 HTTP 请求并用 Spring 集成 HTTP 入站适配器接收它是多么简单。我们创建`MultiValueMap`并用多部分数据填充它。`RestTemplate`通过将其转换为`MultipartHttpServletRequest`来处理其余部分(没有双关语)。这个特定的客户机发送一个包含公司名称和一个图像文件(公司标识)的多部分 HTTP 请求。下面的清单展示了这个示例:
......
此差异已折叠。
此差异已折叠。
# JMS 支持 # JMS 支持
## [](#jms)JMS 支持 ## JMS 支持
Spring 集成提供了用于接收和发送 JMS 消息的通道适配器。 Spring 集成提供了用于接收和发送 JMS 消息的通道适配器。
...@@ -32,7 +32,7 @@ Spring 尽管 JMS 通道适配器旨在用于单向消息传递(仅发送或 ...@@ -32,7 +32,7 @@ Spring 尽管 JMS 通道适配器旨在用于单向消息传递(仅发送或
在 Spring Integration2.2 之前,如果有必要,将为每个请求或回复创建(并删除)一个`TemporaryQueue`。从 Spring Integration2.2 开始,你可以将出站网关配置为使用`MessageListener`容器来接收回复,而不是直接使用新的(或缓存的)`Consumer`来接收每个请求的回复。在这样配置且未提供明确的应答目的地时,每个网关使用一个`TemporaryQueue`,而不是每个请求使用一个。 在 Spring Integration2.2 之前,如果有必要,将为每个请求或回复创建(并删除)一个`TemporaryQueue`。从 Spring Integration2.2 开始,你可以将出站网关配置为使用`MessageListener`容器来接收回复,而不是直接使用新的(或缓存的)`Consumer`来接收每个请求的回复。在这样配置且未提供明确的应答目的地时,每个网关使用一个`TemporaryQueue`,而不是每个请求使用一个。
### [](#jms-inbound-channel-adapter)入站通道适配器 ### 入站通道适配器
入站通道适配器需要对单个`JmsTemplate`实例的引用,或者对`ConnectionFactory``Destination`的引用(你可以提供一个“destinationName”来代替“destination”引用)。下面的示例定义了一个具有`Destination`引用的入站通道适配器: 入站通道适配器需要对单个`JmsTemplate`实例的引用,或者对`ConnectionFactory``Destination`的引用(你可以提供一个“destinationName”来代替“destination”引用)。下面的示例定义了一个具有`Destination`引用的入站通道适配器:
...@@ -99,7 +99,7 @@ Jms.inboundAdapter(connectionFactory) ...@@ -99,7 +99,7 @@ Jms.inboundAdapter(connectionFactory)
.configureJmsTemplate(template -> template.receiveTimeout(-1)) .configureJmsTemplate(template -> template.receiveTimeout(-1))
``` ```
#### [](#jms-ib-transactions)事务 #### 事务
从版本 4.0 开始,入站通道适配器支持`session-transacted`属性。在较早的版本中,你必须插入一个`JmsTemplate`,并将`sessionTransacted`设置为`true`。(适配器确实允许你将`acknowledge`属性设置为`transacted`,但这是不正确的,并且不工作)。 从版本 4.0 开始,入站通道适配器支持`session-transacted`属性。在较早的版本中,你必须插入一个`JmsTemplate`,并将`sessionTransacted`设置为`true`。(适配器确实允许你将`acknowledge`属性设置为`transacted`,但这是不正确的,并且不工作)。
...@@ -107,7 +107,7 @@ Jms.inboundAdapter(connectionFactory) ...@@ -107,7 +107,7 @@ Jms.inboundAdapter(connectionFactory)
如果你希望整个流是事务性的(例如,如果有一个下游出站通道适配器),则必须使用`transactional`poller 和`JmsTransactionManager`。或者,考虑使用`jms-message-driven-channel-adapter`并将`acknowledge`设置为`transacted`(默认值)。 如果你希望整个流是事务性的(例如,如果有一个下游出站通道适配器),则必须使用`transactional`poller 和`JmsTransactionManager`。或者,考虑使用`jms-message-driven-channel-adapter`并将`acknowledge`设置为`transacted`(默认值)。
### [](#jms-message-driven-channel-adapter)消息驱动通道适配器 ### 消息驱动通道适配器
`message-driven-channel-adapter`要求引用 Spring `MessageListener`容器的实例(`AbstractMessageListenerContainer`的任意子类),或者同时引用`ConnectionFactory``Destination`(可以提供一个“destinationName”来代替“destination”引用)。下面的示例用`Destination`引用定义了消息驱动的通道适配器: `message-driven-channel-adapter`要求引用 Spring `MessageListener`容器的实例(`AbstractMessageListenerContainer`的任意子类),或者同时引用`ConnectionFactory``Destination`(可以提供一个“destinationName”来代替“destination”引用)。下面的示例用`Destination`引用定义了消息驱动的通道适配器:
...@@ -191,11 +191,11 @@ XML ...@@ -191,11 +191,11 @@ XML
从版本 5.1 开始,当端点在应用程序保持运行时停止时,底层侦听器容器将被关闭,从而关闭其共享连接和消费者。以前,连接和消费者保持开放。要恢复到以前的行为,请将`JmsMessageDrivenEndpoint`上的`shutdownContainerOnStop`设置为`false` 从版本 5.1 开始,当端点在应用程序保持运行时停止时,底层侦听器容器将被关闭,从而关闭其共享连接和消费者。以前,连接和消费者保持开放。要恢复到以前的行为,请将`JmsMessageDrivenEndpoint`上的`shutdownContainerOnStop`设置为`false`
#### [](#jms-md-conversion-errors)入站转换错误 #### 入站转换错误
从版本 4.2 开始,“错误通道”也用于转换错误。在此之前,如果 JMS`<message-driven-channel-adapter/>``<inbound-gateway/>`由于转换错误而无法发送消息,则会将异常抛回容器。如果容器被配置为使用事务,则消息将被回滚并反复重新交付。转换过程发生在消息构造之前和期间,以便不会将此类错误发送到“错误通道”。现在,这样的转换异常会导致`ErrorMessage`被发送到“错误通道”,但`payload`除外。如果你希望事务回滚并定义了“错误通道”,那么“错误通道”上的集成流必须重新抛出异常(或其他异常)。如果错误流没有抛出异常,则提交事务并删除消息。如果没有定义“错误通道”,则异常将像以前一样被抛回容器。 从版本 4.2 开始,“错误通道”也用于转换错误。在此之前,如果 JMS`<message-driven-channel-adapter/>``<inbound-gateway/>`由于转换错误而无法发送消息,则会将异常抛回容器。如果容器被配置为使用事务,则消息将被回滚并反复重新交付。转换过程发生在消息构造之前和期间,以便不会将此类错误发送到“错误通道”。现在,这样的转换异常会导致`ErrorMessage`被发送到“错误通道”,但`payload`除外。如果你希望事务回滚并定义了“错误通道”,那么“错误通道”上的集成流必须重新抛出异常(或其他异常)。如果错误流没有抛出异常,则提交事务并删除消息。如果没有定义“错误通道”,则异常将像以前一样被抛回容器。
### [](#jms-outbound-channel-adapter)出站通道适配器 ### 出站通道适配器
`JmsSendingMessageHandler`实现了`MessageHandler`接口,并且能够将 Spring 集成`Messages`转换为 JMS 消息,然后发送到 JMS 目的地。它需要一个`jmsTemplate`引用,或者同时需要`jmsConnectionFactory``destination`引用(`destinationName`可以用来代替`destination`)。与入站通道适配器一样,配置此适配器的最简单方法是使用名称空间支持。以下配置生成一个适配器,该适配器接收来自`exampleChannel`的 Spring 集成消息,将这些消息转换为 JMS 消息,并将它们发送到 Bean 名称为`outQueue`的 JMS 目标引用: `JmsSendingMessageHandler`实现了`MessageHandler`接口,并且能够将 Spring 集成`Messages`转换为 JMS 消息,然后发送到 JMS 目的地。它需要一个`jmsTemplate`引用,或者同时需要`jmsConnectionFactory``destination`引用(`destinationName`可以用来代替`destination`)。与入站通道适配器一样,配置此适配器的最简单方法是使用名称空间支持。以下配置生成一个适配器,该适配器接收来自`exampleChannel`的 Spring 集成消息,将这些消息转换为 JMS 消息,并将它们发送到 Bean 名称为`outQueue`的 JMS 目标引用:
...@@ -258,11 +258,11 @@ XML ...@@ -258,11 +258,11 @@ XML
time-to-live-expression="headers.jms_expiration - T(System).currentTimeMillis()"/> time-to-live-expression="headers.jms_expiration - T(System).currentTimeMillis()"/>
``` ```
#### [](#jms-ob-transactions)事务 #### 事务
从版本 4.0 开始,出站通道适配器支持`session-transacted`属性。在较早的版本中,你必须插入一个`JmsTemplate`,并将`sessionTransacted`设置为`true`。现在,该属性在内置的默认值`JmsTemplate`上设置属性。如果存在事务(可能来自上游`message-driven-channel-adapter`),则在同一事务中执行发送操作。否则,将启动一个新的事务。 从版本 4.0 开始,出站通道适配器支持`session-transacted`属性。在较早的版本中,你必须插入一个`JmsTemplate`,并将`sessionTransacted`设置为`true`。现在,该属性在内置的默认值`JmsTemplate`上设置属性。如果存在事务(可能来自上游`message-driven-channel-adapter`),则在同一事务中执行发送操作。否则,将启动一个新的事务。
### [](#jms-inbound-gateway)入站网关 ### 入站网关
Spring Integration 的消息驱动 JMS Inbound-Gateway 委托给`MessageListener`容器,支持动态调整并发消费者,还可以处理回复。入站网关需要引用`ConnectionFactory`和请求`Destination`(或“requestDestationName”)。下面的示例定义了一个 JMS,该 JMS 从 Bean ID 引用的 JMS 队列接收,并发送到名为的 Spring 集成通道: Spring Integration 的消息驱动 JMS Inbound-Gateway 委托给`MessageListener`容器,支持动态调整并发消费者,还可以处理回复。入站网关需要引用`ConnectionFactory`和请求`Destination`(或“requestDestationName”)。下面的示例定义了一个 JMS,该 JMS 从 Bean ID 引用的 JMS 队列接收,并发送到名为的 Spring 集成通道:
...@@ -298,7 +298,7 @@ Spring Integration 的消息驱动 JMS Inbound-Gateway 委托给`MessageListener ...@@ -298,7 +298,7 @@ Spring Integration 的消息驱动 JMS Inbound-Gateway 委托给`MessageListener
从版本 5.1 开始,当端点在应用程序保持运行时停止时,底层侦听器容器将被关闭,从而关闭其共享连接和消费者。以前,连接和消费者保持开放。要恢复到以前的行为,请将`JmsInboundGateway`上的`shutdownContainerOnStop`设置为`false` 从版本 5.1 开始,当端点在应用程序保持运行时停止时,底层侦听器容器将被关闭,从而关闭其共享连接和消费者。以前,连接和消费者保持开放。要恢复到以前的行为,请将`JmsInboundGateway`上的`shutdownContainerOnStop`设置为`false`
### [](#jms-outbound-gateway)出站网关 ### 出站网关
出站网关从 Spring 集成消息创建 JMS 消息,并将它们发送到“请求-目的地”。然后,它通过使用选择器从你配置的“reply-destination”接收 JMS 回复消息,或者,如果没有提供“reply-destination”,则通过创建 JMS`TemporaryQueue`实例来处理 JMS 回复消息。 出站网关从 Spring 集成消息创建 JMS 消息,并将它们发送到“请求-目的地”。然后,它通过使用选择器从你配置的“reply-destination”接收 JMS 回复消息,或者,如果没有提供“reply-destination”,则通过创建 JMS`TemporaryQueue`实例来处理 JMS 回复消息。
...@@ -316,7 +316,7 @@ Spring Integration 的消息驱动 JMS Inbound-Gateway 委托给`MessageListener ...@@ -316,7 +316,7 @@ Spring Integration 的消息驱动 JMS Inbound-Gateway 委托给`MessageListener
“出站网关”有效负载提取属性与“入站网关”的有效负载提取属性是反相关的(参见[先前的讨论](#jms-message-driven-channel-adapter))。这意味着“extract-request-payload”属性值应用于正在转换为 JMS 消息的 Spring 集成消息,该消息将作为请求发送。“extract-reply-payload”属性值应用于作为答复接收的 JMS 消息,然后将其转换为 Spring 集成消息,随后将其发送到“replacy-channel”,如前面的配置示例所示。 “出站网关”有效负载提取属性与“入站网关”的有效负载提取属性是反相关的(参见[先前的讨论](#jms-message-driven-channel-adapter))。这意味着“extract-request-payload”属性值应用于正在转换为 JMS 消息的 Spring 集成消息,该消息将作为请求发送。“extract-reply-payload”属性值应用于作为答复接收的 JMS 消息,然后将其转换为 Spring 集成消息,随后将其发送到“replacy-channel”,如前面的配置示例所示。
#### [](#jms-outbound-gateway-reply-listener)使用`<reply-listener/>` #### 使用`<reply-listener/>`
Spring Integration2.2 引入了一种用于处理答复的替代技术。如果你在网关中添加一个`<reply-listener/>`子元素,而不是为每个回复创建一个使用者,那么将使用一个`MessageListener`容器来接收回复并将其交给请求线程。这提供了许多性能优势,并缓解了[早些时候的警告](#jms-outbound-gateway-memory-caution)中描述的缓存消费者内存利用问题。 Spring Integration2.2 引入了一种用于处理答复的替代技术。如果你在网关中添加一个`<reply-listener/>`子元素,而不是为每个回复创建一个使用者,那么将使用一个`MessageListener`容器来接收回复并将其交给请求线程。这提供了许多性能优势,并缓解了[早些时候的警告](#jms-outbound-gateway-memory-caution)中描述的缓存消费者内存利用问题。
...@@ -340,13 +340,13 @@ Spring Integration2.2 引入了一种用于处理答复的替代技术。如果 ...@@ -340,13 +340,13 @@ Spring Integration2.2 引入了一种用于处理答复的替代技术。如果
侦听器非常轻量级,我们预计,在大多数情况下,你只需要一个消费者。但是,你可以添加诸如`concurrent-consumers``max-concurrent-consumers`等属性。有关受支持的属性的完整列表,请参见模式,以及[Spring JMS documentation](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/jms.html)的含义。 侦听器非常轻量级,我们预计,在大多数情况下,你只需要一个消费者。但是,你可以添加诸如`concurrent-consumers``max-concurrent-consumers`等属性。有关受支持的属性的完整列表,请参见模式,以及[Spring JMS documentation](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/jms.html)的含义。
#### [](#idle-reply-listeners)空闲回复侦听器 #### 空闲回复侦听器
从版本 4.2 开始,你可以根据需要启动应答侦听器(并在空闲时间之后停止它),而不是在网关的生命周期中运行。如果你在应用程序上下文中有许多网关,而这些网关大部分都是空闲的,那么这可能是有用的。其中一种情况是上下文中使用 Spring 集成和 JMS 进行分区分发的许多(非活动的)分区[Spring Batch](https://spring.io/projects/spring-batch)作业。如果所有的应答侦听器都是活动的,那么 JMS 代理为每个网关都有一个活动的消费者。通过启用空闲超时,每个使用者仅在相应的批处理作业运行时存在(并在其完成后的很短时间内存在)。 从版本 4.2 开始,你可以根据需要启动应答侦听器(并在空闲时间之后停止它),而不是在网关的生命周期中运行。如果你在应用程序上下文中有许多网关,而这些网关大部分都是空闲的,那么这可能是有用的。其中一种情况是上下文中使用 Spring 集成和 JMS 进行分区分发的许多(非活动的)分区[Spring Batch](https://spring.io/projects/spring-batch)作业。如果所有的应答侦听器都是活动的,那么 JMS 代理为每个网关都有一个活动的消费者。通过启用空闲超时,每个使用者仅在相应的批处理作业运行时存在(并在其完成后的很短时间内存在)。
`idle-reply-listener-timeout`in[属性引用](#jms-og-attributes) `idle-reply-listener-timeout`in[属性引用](#jms-og-attributes)
#### [](#gateway-reply-correlation)网关回复相关性 #### 网关回复相关性
本节描述了用于响应相关性的机制(确保发起网关仅接收对其请求的响应),具体取决于网关的配置方式。有关此处讨论的属性的完整描述,请参见[属性引用](#jms-og-attributes) 本节描述了用于响应相关性的机制(确保发起网关仅接收对其请求的响应),具体取决于网关的配置方式。有关此处讨论的属性的完整描述,请参见[属性引用](#jms-og-attributes)
...@@ -429,7 +429,7 @@ Spring Integration2.2 引入了一种用于处理答复的替代技术。如果 ...@@ -429,7 +429,7 @@ Spring Integration2.2 引入了一种用于处理答复的替代技术。如果
回复侦听器不允许使用用户提供的相关 ID。网关不使用此配置初始化。 回复侦听器不允许使用用户提供的相关 ID。网关不使用此配置初始化。
#### [](#jms-async-gateway)异步网关 #### 异步网关
从版本 4.3 开始,在配置出站网关时,你现在可以指定`async="true"`(或者在 Java 中是`setAsync(true)`)。 从版本 4.3 开始,在配置出站网关时,你现在可以指定`async="true"`(或者在 Java 中是`setAsync(true)`)。
...@@ -437,7 +437,7 @@ Spring Integration2.2 引入了一种用于处理答复的替代技术。如果 ...@@ -437,7 +437,7 @@ Spring Integration2.2 引入了一种用于处理答复的替代技术。如果
`async`需要`<reply-listener/>`(或者在使用 Java 配置时`setUseReplyContainer(true)`)。它还需要指定`correlationKey`(通常`JMSCorrelationID`)。如果不满足上述任一条件,`async`将被忽略。 `async`需要`<reply-listener/>`(或者在使用 Java 配置时`setUseReplyContainer(true)`)。它还需要指定`correlationKey`(通常`JMSCorrelationID`)。如果不满足上述任一条件,`async`将被忽略。
#### [](#jms-og-attributes)属性引用 #### 属性引用
下面的清单显示了`outbound-gateway`的所有可用属性: 下面的清单显示了`outbound-gateway`的所有可用属性:
...@@ -503,7 +503,7 @@ Spring Integration2.2 引入了一种用于处理答复的替代技术。如果 ...@@ -503,7 +503,7 @@ Spring Integration2.2 引入了一种用于处理答复的替代技术。如果
|**26**|见[异步网关](#jms-async-gateway)。| |**26**|见[异步网关](#jms-async-gateway)。|
|**27**|当包含此元素时,将通过异步`MessageListenerContainer`接收答复,而不是为每个答复创建一个消费者。<br/>在许多情况下,这可以更有效。| |**27**|当包含此元素时,将通过异步`MessageListenerContainer`接收答复,而不是为每个答复创建一个消费者。<br/>在许多情况下,这可以更有效。|
### [](#jms-header-mapping)映射消息头到和来自 JMS 消息 ### 映射消息头到和来自 JMS 消息
JMS 消息可以包含元信息,如 JMS API 头和简单属性。你可以使用`JmsHeaderMapper`将这些消息映射到 Spring 集成消息头。JMS API 头被传递给适当的 setter 方法(例如`setJMSReplyTo`),而其他头则被复制到 JMS 消息的一般属性中。JMS 出站网关使用`JmsHeaderMapper`的默认实现来引导,它将映射标准的 JMS API 头以及原语或`String`消息头。还可以通过使用入站和出站网关的`header-mapper`属性提供自定义的头映射器。 JMS 消息可以包含元信息,如 JMS API 头和简单属性。你可以使用`JmsHeaderMapper`将这些消息映射到 Spring 集成消息头。JMS API 头被传递给适当的 setter 方法(例如`setJMSReplyTo`),而其他头则被复制到 JMS 消息的一般属性中。JMS 出站网关使用`JmsHeaderMapper`的默认实现来引导,它将映射标准的 JMS API 头以及原语或`String`消息头。还可以通过使用入站和出站网关的`header-mapper`属性提供自定义的头映射器。
...@@ -530,7 +530,7 @@ public DefaultJmsHeaderMapper jmsHeaderMapper() { ...@@ -530,7 +530,7 @@ public DefaultJmsHeaderMapper jmsHeaderMapper() {
这些 JMS 属性分别映射到`JmsHeaders.DELIVERY_MODE``JmsHeaders.EXPIRATION` Spring 消息头。 这些 JMS 属性分别映射到`JmsHeaders.DELIVERY_MODE``JmsHeaders.EXPIRATION` Spring 消息头。
### [](#jms-conversion-and-marshalling)消息转换、编组和解组 ### 消息转换、编组和解组
如果需要转换消息,所有 JMS 适配器和网关都允许你通过设置`message-converter`属性来提供`MessageConverter`。要做到这一点,请提供在相同的应用程序上下文中可用的`MessageConverter`实例的 Bean 名称。另外,为了提供与 Marshaller 和 Unmarshaller 接口的某种一致性, Spring 提供了`MarshallingMessageConverter`,你可以使用自己的自定义 Marshaller 和 Unmarshaller 对其进行配置。下面的示例展示了如何做到这一点。 如果需要转换消息,所有 JMS 适配器和网关都允许你通过设置`message-converter`属性来提供`MessageConverter`。要做到这一点,请提供在相同的应用程序上下文中可用的`MessageConverter`实例的 Bean 名称。另外,为了提供与 Marshaller 和 Unmarshaller 接口的某种一致性, Spring 提供了`MarshallingMessageConverter`,你可以使用自己的自定义 Marshaller 和 Unmarshaller 对其进行配置。下面的示例展示了如何做到这一点。
...@@ -553,7 +553,7 @@ public DefaultJmsHeaderMapper jmsHeaderMapper() { ...@@ -553,7 +553,7 @@ public DefaultJmsHeaderMapper jmsHeaderMapper() {
| |当你提供自己的`MessageConverter`实例时,它仍然被包装在`HeaderMappingMessageConverter`中。<br/>这意味着“extract-request-payload”和“extract-reply-payload”属性可能会影响传递给转换器的实际对象。<br/>`HeaderMappingMessageConverter`本身委托给目标`MessageConverter`,同时还将 Spring 集成`MessageHeaders`映射到 JMS 消息属性并再次返回。| | |当你提供自己的`MessageConverter`实例时,它仍然被包装在`HeaderMappingMessageConverter`中。<br/>这意味着“extract-request-payload”和“extract-reply-payload”属性可能会影响传递给转换器的实际对象。<br/>`HeaderMappingMessageConverter`本身委托给目标`MessageConverter`,同时还将 Spring 集成`MessageHeaders`映射到 JMS 消息属性并再次返回。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#jms-channel)JMS 支持的消息通道 ### JMS 支持的消息通道
前面介绍的通道适配器和网关都是为与其他外部系统集成的应用程序设计的。入站选项假设其他系统正在向 JMS 目的地发送 JMS 消息,出站选项假设其他系统正在从该目的地接收消息。 Spring 集成应用程序可以是也可以不是另一种系统。当然,当发送 Spring 集成消息实例作为 JMS 消息本身的主体时(将’extract-payload’值设置为`false`),假定另一个系统是基于 Spring 集成的。然而,这绝不是一项要求。这种灵活性是使用基于消息的集成选项并抽象“通道”(在 JMS 的情况下是目标)的好处之一。 前面介绍的通道适配器和网关都是为与其他外部系统集成的应用程序设计的。入站选项假设其他系统正在向 JMS 目的地发送 JMS 消息,出站选项假设其他系统正在从该目的地接收消息。 Spring 集成应用程序可以是也可以不是另一种系统。当然,当发送 Spring 集成消息实例作为 JMS 消息本身的主体时(将’extract-payload’值设置为`false`),假定另一个系统是基于 Spring 集成的。然而,这绝不是一项要求。这种灵活性是使用基于消息的集成选项并抽象“通道”(在 JMS 的情况下是目标)的好处之一。
...@@ -591,7 +591,7 @@ public DefaultJmsHeaderMapper jmsHeaderMapper() { ...@@ -591,7 +591,7 @@ public DefaultJmsHeaderMapper jmsHeaderMapper() {
对于`<publish-subscribe-channel />`,对于持久订阅,将`durable`属性设置为`true`,对于共享订阅,将`subscription-shared`属性设置为`subscription-shared`(需要一个 JMS2.0 代理,并且自版本 4.2 以来一直可用)。使用`subscription`来命名订阅。 对于`<publish-subscribe-channel />`,对于持久订阅,将`durable`属性设置为`true`,对于共享订阅,将`subscription-shared`属性设置为`subscription-shared`(需要一个 JMS2.0 代理,并且自版本 4.2 以来一直可用)。使用`subscription`来命名订阅。
### [](#jms-selectors)使用 JMS 消息选择器 ### 使用 JMS 消息选择器
使用 JMS 消息选择器,你可以基于 JMS 头和 JMS 属性过滤[JMS 消息](https://docs.oracle.com/javaee/6/api/javax/jms/Message.html)。例如,如果希望侦听其自定义 JMS 头属性`myHeaderProperty`等于`something`的消息,则可以指定以下表达式: 使用 JMS 消息选择器,你可以基于 JMS 头和 JMS 属性过滤[JMS 消息](https://docs.oracle.com/javaee/6/api/javax/jms/Message.html)。例如,如果希望侦听其自定义 JMS 头属性`myHeaderProperty`等于`something`的消息,则可以指定以下表达式:
...@@ -614,7 +614,7 @@ myHeaderProperty = 'something' ...@@ -614,7 +614,7 @@ myHeaderProperty = 'something'
| |不能使用 JMS 消息选择器引用消息主体的值。| | |不能使用 JMS 消息选择器引用消息主体的值。|
|---|------------------------------------------------------------------------| |---|------------------------------------------------------------------------|
### [](#jms-samples)JMS 样本 ### JMS 样本
要对这些 JMS 适配器进行实验,请查看 Spring Integration Samples Git 存储库中的 JMS 示例,网址为[https://github.com/spring-projects/spring-integration-samples/tree/master/basic/jms](https://github.com/SpringSource/spring-integration-samples/tree/main/basic/jms) 要对这些 JMS 适配器进行实验,请查看 Spring Integration Samples Git 存储库中的 JMS 示例,网址为[https://github.com/spring-projects/spring-integration-samples/tree/master/basic/jms](https://github.com/SpringSource/spring-integration-samples/tree/main/basic/jms)
......
# JMX 支持 # JMX 支持
### [](#jmx)JMX 支持 ### JMX 支持
Spring 集成提供了用于接收和发布 JMX 通知的通道适配器。 Spring 集成提供了用于接收和发布 JMX 通知的通道适配器。
...@@ -24,7 +24,7 @@ compile "org.springframework.integration:spring-integration-jmx:5.5.9" ...@@ -24,7 +24,7 @@ compile "org.springframework.integration:spring-integration-jmx:5.5.9"
入站通道适配器允许轮询 JMX MBean 属性值,出站通道适配器允许调用 JMX MBean 操作。 入站通道适配器允许轮询 JMX MBean 属性值,出站通道适配器允许调用 JMX MBean 操作。
#### [](#jmx-notification-listening-channel-adapter)通知-监听通道适配器 #### 通知-监听通道适配器
通知监听通道适配器需要一个 JMX,用于发布此侦听器应注册到的通知的 MBean。一个非常简单的配置可能类似于以下内容: 通知监听通道适配器需要一个 JMX,用于发布此侦听器应注册到的通知的 MBean。一个非常简单的配置可能类似于以下内容:
...@@ -53,7 +53,7 @@ compile "org.springframework.integration:spring-integration-jmx:5.5.9" ...@@ -53,7 +53,7 @@ compile "org.springframework.integration:spring-integration-jmx:5.5.9"
| |仅对于这个组件,`object-name`属性可以包含一个对象名模式(例如,<br/>“org.something:type=mytype,name=\*”)。,在这种情况下,适配器接收来自所有具有匹配该模式的对象名的 MBean 的通知。,此外,<br/>`object-name`属性可以包含对`<util:list>`对象名称模式的 SPEL 引用,如下例所示:<br/><br/>```<br/><jmx:notification-listening-channel-adapter id="manyNotificationsAdapter"<br/> channel="manyNotificationsChannel"<br/> object-name="#{patterns}"/><br/><br/><util:list id="patterns"><br/> <value>org.foo:type=Foo,name=*</value><br/> <value>org.foo:type=Bar,name=*</value><br/></util:list><br/>```<br/>启用调试级别日志时,将记录定位的 MBean 的名称。| | |仅对于这个组件,`object-name`属性可以包含一个对象名模式(例如,<br/>“org.something:type=mytype,name=\*”)。,在这种情况下,适配器接收来自所有具有匹配该模式的对象名的 MBean 的通知。,此外,<br/>`object-name`属性可以包含对`<util:list>`对象名称模式的 SPEL 引用,如下例所示:<br/><br/>```<br/><jmx:notification-listening-channel-adapter id="manyNotificationsAdapter"<br/> channel="manyNotificationsChannel"<br/> object-name="#{patterns}"/><br/><br/><util:list id="patterns"><br/> <value>org.foo:type=Foo,name=*</value><br/> <value>org.foo:type=Bar,name=*</value><br/></util:list><br/>```<br/>启用调试级别日志时,将记录定位的 MBean 的名称。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### [](#jmx-notification-publishing-channel-adapter)通知-发布通道适配器 #### 通知-发布通道适配器
通知发布通道适配器相对简单。它在配置中只需要一个 JMX 对象名,如下例所示: 通知发布通道适配器相对简单。它在配置中只需要一个 JMX 对象名,如下例所示:
...@@ -80,7 +80,7 @@ JMX 通知还具有`type`,并且应该是以点分隔的`String`。有两种 ...@@ -80,7 +80,7 @@ JMX 通知还具有`type`,并且应该是以点分隔的`String`。有两种
default-notification-type="some.default.type"/> default-notification-type="some.default.type"/>
``` ```
#### [](#jmx-attribute-polling-channel-adapter)属性-轮询通道适配器 #### 属性-轮询通道适配器
当你需要定期检查通过 MBean 作为托管属性提供的某些值时,属性轮询通道适配器非常有用。可以以与 Spring 集成中的任何其他轮询适配器相同的方式配置 Poller(或者可以依赖默认的 Poller)。需要`object-name``attribute-name`。还需要一个 mBeanServer 引用。但是,默认情况下,它会自动检查名为`mbeanServer`的 Bean,与通知侦听通道适配器[前面描述的](#jmx-notification-listening-channel-adapter)相同。下面的示例展示了如何使用 XML 配置属性轮询通道适配器: 当你需要定期检查通过 MBean 作为托管属性提供的某些值时,属性轮询通道适配器非常有用。可以以与 Spring 集成中的任何其他轮询适配器相同的方式配置 Poller(或者可以依赖默认的 Poller)。需要`object-name``attribute-name`。还需要一个 mBeanServer 引用。但是,默认情况下,它会自动检查名为`mbeanServer`的 Bean,与通知侦听通道适配器[前面描述的](#jmx-notification-listening-channel-adapter)相同。下面的示例展示了如何使用 XML 配置属性轮询通道适配器:
...@@ -93,7 +93,7 @@ JMX 通知还具有`type`,并且应该是以点分隔的`String`。有两种 ...@@ -93,7 +93,7 @@ JMX 通知还具有`type`,并且应该是以点分隔的`String`。有两种
</int-jmx:attribute-polling-channel-adapter> </int-jmx:attribute-polling-channel-adapter>
``` ```
#### [](#tree-polling-channel-adapter)树轮询通道适配器 #### 树轮询通道适配器
树轮询通道适配器查询 JMX MBean 树,并发送一条带有有效负载的消息,该负载是与查询匹配的对象的图形。默认情况下,MBean 映射到原语和简单对象,例如`Map``List`和数组。这样做允许简单地转换到(例如)JSON。还需要一个 mBeanServer 引用。但是,默认情况下,它会自动检查名为`mbeanServer`的 Bean,与通知监听通道适配器[前面描述的](#jmx-notification-listening-channel-adapter)相同。下面的示例展示了如何使用 XML 配置树轮询通道适配器: 树轮询通道适配器查询 JMX MBean 树,并发送一条带有有效负载的消息,该负载是与查询匹配的对象的图形。默认情况下,MBean 映射到原语和简单对象,例如`Map``List`和数组。这样做允许简单地转换到(例如)JSON。还需要一个 mBeanServer 引用。但是,默认情况下,它会自动检查名为`mbeanServer`的 Bean,与通知监听通道适配器[前面描述的](#jmx-notification-listening-channel-adapter)相同。下面的示例展示了如何使用 XML 配置树轮询通道适配器:
...@@ -109,7 +109,7 @@ JMX 通知还具有`type`,并且应该是以点分隔的`String`。有两种 ...@@ -109,7 +109,7 @@ JMX 通知还具有`type`,并且应该是以点分隔的`String`。有两种
Spring 集成提供了两个标准过滤器。`NamedFieldsMBeanAttributeFilter`允许你指定要包含的属性列表。`NotNamedFieldsMBeanAttributeFilter`允许你指定要排除的属性列表。你还可以实现自己的过滤器。 Spring 集成提供了两个标准过滤器。`NamedFieldsMBeanAttributeFilter`允许你指定要包含的属性列表。`NotNamedFieldsMBeanAttributeFilter`允许你指定要排除的属性列表。你还可以实现自己的过滤器。
#### [](#jmx-operation-invoking-channel-adapter)操作调用通道适配器 #### 操作调用通道适配器
操作调用通道适配器支持对 MBean 公开的任何托管操作的消息驱动调用。每个调用都需要调用操作名和目标 MBean 的对象名。这两个都必须由适配器配置显式提供,或者分别通过`JmxHeaders.OBJECT_NAME``JmxHeaders.OPERATION_NAME`消息头提供: 操作调用通道适配器支持对 MBean 公开的任何托管操作的消息驱动调用。每个调用都需要调用操作名和目标 MBean 的对象名。这两个都必须由适配器配置显式提供,或者分别通过`JmxHeaders.OBJECT_NAME``JmxHeaders.OPERATION_NAME`消息头提供:
...@@ -125,7 +125,7 @@ Spring 集成提供了两个标准过滤器。`NamedFieldsMBeanAttributeFilter` ...@@ -125,7 +125,7 @@ Spring 集成提供了两个标准过滤器。`NamedFieldsMBeanAttributeFilter`
如果你希望公开一个通道,以便由不需要包含头的消息调用单个公共操作,那么最后一个选项效果很好。 如果你希望公开一个通道,以便由不需要包含头的消息调用单个公共操作,那么最后一个选项效果很好。
#### [](#jmx-operation-invoking-outbound-gateway)操作调用出站网关 #### 操作调用出站网关
Spring 与操作调用通道适配器类似,集成还提供了一个操作调用出站网关,当需要返回值时,可以在处理非 void 操作时使用该网关。返回值作为消息有效负载发送到网关指定的`reply-channel`。下面的示例展示了如何使用 XML 配置操作调用出站网关: Spring 与操作调用通道适配器类似,集成还提供了一个操作调用出站网关,当需要返回值时,可以在处理非 void 操作时使用该网关。返回值作为消息有效负载发送到网关指定的`reply-channel`。下面的示例展示了如何使用 XML 配置操作调用出站网关:
...@@ -138,7 +138,7 @@ Spring 与操作调用通道适配器类似,集成还提供了一个操作调 ...@@ -138,7 +138,7 @@ Spring 与操作调用通道适配器类似,集成还提供了一个操作调
如果不提供`reply-channel`属性,则将回复消息发送到由`IntegrationMessageHeaderAccessor.REPLY_CHANNEL`标头标识的通道。该消息头通常由消息流的入口点自动创建,例如任何网关组件。但是,如果消息流是通过手动创建 Spring 集成消息并将其直接发送到通道来启动的,则必须显式地指定消息头,或者使用`reply-channel`属性。 如果不提供`reply-channel`属性,则将回复消息发送到由`IntegrationMessageHeaderAccessor.REPLY_CHANNEL`标头标识的通道。该消息头通常由消息流的入口点自动创建,例如任何网关组件。但是,如果消息流是通过手动创建 Spring 集成消息并将其直接发送到通道来启动的,则必须显式地指定消息头,或者使用`reply-channel`属性。
#### [](#jmx-mbean-exporter)MBean 出口商 #### MBean 出口商
Spring 当`IntegrationMBeanExporter`被配置时,集成组件本身可以作为 MBean 公开。要创建`IntegrationMBeanExporter`的实例,定义 Bean 并提供对`MBeanServer`的引用和域名(如果需要)。可以省略这个域,在这种情况下,默认域是`org.springframework.integration`。下面的示例展示了如何声明`IntegrationMBeanExporter`实例和关联的`MBeanServer`实例: Spring 当`IntegrationMBeanExporter`被配置时,集成组件本身可以作为 MBean 公开。要创建`IntegrationMBeanExporter`的实例,定义 Bean 并提供对`MBeanServer`的引用和域名(如果需要)。可以省略这个域,在这种情况下,默认域是`org.springframework.integration`。下面的示例展示了如何声明`IntegrationMBeanExporter`实例和关联的`MBeanServer`实例:
...@@ -171,7 +171,7 @@ public class ContextConfiguration { ...@@ -171,7 +171,7 @@ public class ContextConfiguration {
如果需要提供更多选项或具有几个`IntegrationMBeanExporter`bean(例如用于不同的 MBean 服务器或避免与标准 Spring `MBeanExporter`冲突——例如通过`@EnableMBeanExport`),则可以将`IntegrationMBeanExporter`配置为通用 Bean。 如果需要提供更多选项或具有几个`IntegrationMBeanExporter`bean(例如用于不同的 MBean 服务器或避免与标准 Spring `MBeanExporter`冲突——例如通过`@EnableMBeanExport`),则可以将`IntegrationMBeanExporter`配置为通用 Bean。
##### [](#jmx-mbean-features)MBean 对象名 ##### MBean 对象名
应用程序中的所有`MessageChannel``MessageHandler``MessageSource`实例都由 MBean Exporter 包装,以提供管理和监视功能。下表列出了为每个组件类型生成的 JMX 对象名: 应用程序中的所有`MessageChannel``MessageHandler``MessageSource`实例都由 MBean Exporter 包装,以提供管理和监视功能。下表列出了为每个组件类型生成的 JMX 对象名:
...@@ -214,7 +214,7 @@ public class Namer implements ObjectNamingStrategy { ...@@ -214,7 +214,7 @@ public class Namer implements ObjectNamingStrategy {
从版本 5.1 开始;任何 Bean 名称(由对象名称中的`name`键表示),如果它们包含 Java 标识符(或句号`.`)中不允许的任何字符,都将被引用。 从版本 5.1 开始;任何 Bean 名称(由对象名称中的`name`键表示),如果它们包含 Java 标识符(或句号`.`)中不允许的任何字符,都将被引用。
##### [](#jmx-42-improvements)JMX 改进 ##### JMX 改进
版本 4.2 引入了一些重要的改进,代表了对框架中的 JMX 支持的一次相当大的改革。这些结果导致了 JMX 统计数据收集的性能的显著改善,并对其进行了更多的控制。然而,在一些特定的(不常见的)情况下,它对用户代码有一些影响。下文详细介绍了这些变化,必要时请谨慎从事。 版本 4.2 引入了一些重要的改进,代表了对框架中的 JMX 支持的一次相当大的改革。这些结果导致了 JMX 统计数据收集的性能的显著改善,并对其进行了更多的控制。然而,在一些特定的(不常见的)情况下,它对用户代码有一些影响。下文详细介绍了这些变化,必要时请谨慎从事。
...@@ -235,7 +235,7 @@ MBean Exporter Bean 名称模式 ...@@ -235,7 +235,7 @@ MBean Exporter Bean 名称模式
`IntegrationMBeanExporter`不再实现`SmartLifecycle`。这意味着`start()`和`stop()`操作不再可用于注册和取消注册 MBean。MBean 现在在上下文初始化期间注册,在上下文被销毁时取消注册。 `IntegrationMBeanExporter`不再实现`SmartLifecycle`。这意味着`start()`和`stop()`操作不再可用于注册和取消注册 MBean。MBean 现在在上下文初始化期间注册,在上下文被销毁时取消注册。
##### [](#jmx-mbean-shutdown)有序关停托管运行 ##### 有序关停托管运行
MBean Exporter 允许一个 JMX 操作以有序的方式关闭应用程序。它是在停止 JVM 之前使用的。下面的示例展示了如何使用它: MBean Exporter 允许一个 JMX 操作以有序的方式关闭应用程序。它是在停止 JVM 之前使用的。下面的示例展示了如何使用它:
......
此差异已折叠。
此差异已折叠。
# Kotlin DSL # Kotlin DSL
## [](#kotlin-dsl) Kotlin dsl ## Kotlin dsl
Kotlin DSL 是[Java DSL](./dsl.html#java-dsl)的包装器和扩展,其目的是使 Spring 上的集成开发尽可能平滑和简单,并与现有的 Java API 和 Kotlin 语言特定的结构具有互操作性。 Kotlin DSL 是[Java DSL](./dsl.html#java-dsl)的包装器和扩展,其目的是使 Spring 上的集成开发尽可能平滑和简单,并与现有的 Java API 和 Kotlin 语言特定的结构具有互操作性。
......
# 邮件支持 # 邮件支持
## [](#mail)邮件支持 ## 邮件支持
本节描述如何在 Spring 集成中处理邮件消息。 本节描述如何在 Spring 集成中处理邮件消息。
...@@ -24,7 +24,7 @@ compile "org.springframework.integration:spring-integration-mail:5.5.9" ...@@ -24,7 +24,7 @@ compile "org.springframework.integration:spring-integration-mail:5.5.9"
`javax.mail:javax.mail-api`必须通过特定于供应商的实现来包含。 `javax.mail:javax.mail-api`必须通过特定于供应商的实现来包含。
### [](#mail-outbound)邮件发送通道适配器 ### 邮件发送通道适配器
Spring 集成提供了对带有`MailSendingMessageHandler`的出站电子邮件的支持。它将委托给 Spring 的`爪哇MailSender`的一个配置实例,如下例所示: Spring 集成提供了对带有`MailSendingMessageHandler`的出站电子邮件的支持。它将委托给 Spring 的`爪哇MailSender`的一个配置实例,如下例所示:
...@@ -50,7 +50,7 @@ Spring 集成提供了对带有`MailSendingMessageHandler`的出站电子邮件 ...@@ -50,7 +50,7 @@ Spring 集成提供了对带有`MailSendingMessageHandler`的出站电子邮件
| |`MailHeaders`还可以重写相应的`MailMessage`值。<br/>例如,如果`MailMessage.to`被设置为’[[电子邮件保护]](/cdn-cgi/l/email-protection#d0a4b8b8b9beb7e190a4b8b9beb7a3feb3bfbbd)’并提供了`MailHeaders.TO`消息头,则优先处理并重写`MailMessage`中的对应值。| | |`MailHeaders`还可以重写相应的`MailMessage`值。<br/>例如,如果`MailMessage.to`被设置为’[[电子邮件保护]](/cdn-cgi/l/email-protection#d0a4b8b8b9beb7e190a4b8b9beb7a3feb3bfbbd)’并提供了`MailHeaders.TO`消息头,则优先处理并重写`MailMessage`中的对应值。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#mail-inbound)邮件接收通道适配器 ### 邮件接收通道适配器
Spring 集成还提供了对带有`MailReceivingMessageSource`的入站电子邮件的支持。它将委托给 Spring 集成自己的`MailReceiver`接口的已配置实例。有两种实现方式:`Pop3MailReceiver``ImapMailReceiver`。实例化这两种方法中任何一种的最简单方法是将邮件存储的“URI”传递给接收者的构造函数,如下例所示: Spring 集成还提供了对带有`MailReceivingMessageSource`的入站电子邮件的支持。它将委托给 Spring 集成自己的`MailReceiver`接口的已配置实例。有两种实现方式:`Pop3MailReceiver``ImapMailReceiver`。实例化这两种方法中任何一种的最简单方法是将邮件存储的“URI”传递给接收者的构造函数,如下例所示:
...@@ -90,7 +90,7 @@ if (closeableResource != null) { ...@@ -90,7 +90,7 @@ if (closeableResource != null) {
从版本 5.4 开始,现在可以返回`MimeMessage`,不需要任何转换或急切的内容加载。该功能是通过以下选项组合启用的:不提供`headerMapper``simpleContent`属性是`false``autoCloseFolder`属性是`false``MimeMessage`作为产生的 Spring 消息的有效负载而存在。在这种情况下,唯一填充的头是上面提到的`IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE`,用于在`MimeMessage`的处理完成时必须关闭的文件夹。 从版本 5.4 开始,现在可以返回`MimeMessage`,不需要任何转换或急切的内容加载。该功能是通过以下选项组合启用的:不提供`headerMapper``simpleContent`属性是`false``autoCloseFolder`属性是`false``MimeMessage`作为产生的 Spring 消息的有效负载而存在。在这种情况下,唯一填充的头是上面提到的`IntegrationMessageHeaderAccessor.CLOSEABLE_RESOURCE`,用于在`MimeMessage`的处理完成时必须关闭的文件夹。
### [](#mail-mapping)入站邮件消息映射 ### 入站邮件消息映射
默认情况下,入站适配器产生的消息的有效负载是 RAW`MimeMessage`。你可以使用该对象查询标题和内容。从版本 4.3 开始,你可以提供`HeaderMapper<MimeMessage>`来将标题映射到`MessageHeaders`。 Spring 为方便起见,集成为此目的提供了`DefaultMailHeaderMapper`。它映射了以下标题: 默认情况下,入站适配器产生的消息的有效负载是 RAW`MimeMessage`。你可以使用该对象查询标题和内容。从版本 4.3 开始,你可以提供`HeaderMapper<MimeMessage>`来将标题映射到`MessageHeaders`。 Spring 为方便起见,集成为此目的提供了`DefaultMailHeaderMapper`。它映射了以下标题:
...@@ -164,7 +164,7 @@ XML ...@@ -164,7 +164,7 @@ XML
从版本 5.4 开始,当没有`headerMapper`被提供时,`autoCloseFolder``false``simpleContent``false`,则在产生的 Spring 消息的有效负载中以原样返回`MimeMessage`。通过这种方式,`MimeMessage`的内容在引用时按需加载,稍后在流程中加载。上面提到的所有转换仍然有效。 从版本 5.4 开始,当没有`headerMapper`被提供时,`autoCloseFolder``false``simpleContent``false`,则在产生的 Spring 消息的有效负载中以原样返回`MimeMessage`。通过这种方式,`MimeMessage`的内容在引用时按需加载,稍后在流程中加载。上面提到的所有转换仍然有效。
### [](#mail-namespace)邮件命名空间支持 ### 邮件命名空间支持
Spring 集成为与邮件相关的配置提供了一个命名空间。要使用它,请配置以下架构位置: Spring 集成为与邮件相关的配置提供了一个命名空间。要使用它,请配置以下架构位置:
...@@ -302,7 +302,7 @@ public interface SearchTermStrategy { ...@@ -302,7 +302,7 @@ public interface SearchTermStrategy {
| |重要提示:IMAP Peek<br/><br/>从版本 4.1.1 开始,IMAP 邮件接收器使用`mail.imap.peek``mail.imaps.peek`JavaMail 属性,如果指定的话。<br/>以前,接收器忽略了该属性,并且总是设置`PEEK`标志。<br/>现在,如果你显式地将此属性设置为`false`,无论`shouldMarkMessagesRead`的设置如何,消息 ISE 都标记为`\Seen`<br/>如果未指定,则保留先前的行为(PEEK 为`true`)。| | |重要提示:IMAP Peek<br/><br/>从版本 4.1.1 开始,IMAP 邮件接收器使用`mail.imap.peek``mail.imaps.peek`JavaMail 属性,如果指定的话。<br/>以前,接收器忽略了该属性,并且总是设置`PEEK`标志。<br/>现在,如果你显式地将此属性设置为`false`,无论`shouldMarkMessagesRead`的设置如何,消息 ISE 都标记为`\Seen`<br/>如果未指定,则保留先前的行为(PEEK 为`true`)。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### [](#imap-idle-and-lost-connections)IMAP`idle`和丢失连接 #### IMAP`idle`和丢失连接
当使用 IMAP`idle`通道适配器时,与服务器的连接可能会丢失(例如,由于网络故障),并且由于 JavaMail 文档明确指出,实际的 IMAP API 是实验性的,理解 API 中的差异以及在配置 IMAP`idle`适配器时如何处理它们是很重要的。目前, Spring 集成邮件适配器已经用 JavaMail1.4.1 和 JavaMail1.4.3 进行了测试。根据使用的是哪一个,你必须特别注意在自动重新连接时需要设置的一些 JavaMail 属性。 当使用 IMAP`idle`通道适配器时,与服务器的连接可能会丢失(例如,由于网络故障),并且由于 JavaMail 文档明确指出,实际的 IMAP API 是实验性的,理解 API 中的差异以及在配置 IMAP`idle`适配器时如何处理它们是很重要的。目前, Spring 集成邮件适配器已经用 JavaMail1.4.1 和 JavaMail1.4.3 进行了测试。根据使用的是哪一个,你必须特别注意在自动重新连接时需要设置的一些 JavaMail 属性。
...@@ -327,7 +327,7 @@ public interface SearchTermStrategy { ...@@ -327,7 +327,7 @@ public interface SearchTermStrategy {
| |从 3.0 版本开始,当出现异常时,IMAP`idle`适配器会发出应用程序事件(特别是`ImapIdleExceptionEvent`实例)。<br/>这允许应用程序检测并对这些异常执行。<br/>你可以通过使用`<int-event:inbound-channel-adapter>`或任何`ApplicationListener`配置为接收`ImapIdleExceptionEvent`或其超类之一来获得事件。| | |从 3.0 版本开始,当出现异常时,IMAP`idle`适配器会发出应用程序事件(特别是`ImapIdleExceptionEvent`实例)。<br/>这允许应用程序检测并对这些异常执行。<br/>你可以通过使用`<int-event:inbound-channel-adapter>`或任何`ApplicationListener`配置为接收`ImapIdleExceptionEvent`或其超类之一来获得事件。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### [](#imap-seen)不支持`\Recent`时标记 IMAP 消息 ### 不支持`\Recent`时标记 IMAP 消息
如果`shouldMarkMessagesAsRead`为真,则 IMAP 适配器设置`\Seen`标志。 如果`shouldMarkMessagesAsRead`为真,则 IMAP 适配器设置`\Seen`标志。
...@@ -337,7 +337,7 @@ public interface SearchTermStrategy { ...@@ -337,7 +337,7 @@ public interface SearchTermStrategy {
从版本 4.2.2 开始,你可以通过在`MailReceiver`上使用`setUserFlag`来设置用户标志的名称。这样做可以让多个接收者使用不同的标志(只要邮件服务器支持用户标志)。当使用名称空间配置适配器时,`user-flag`属性可用。 从版本 4.2.2 开始,你可以通过在`MailReceiver`上使用`setUserFlag`来设置用户标志的名称。这样做可以让多个接收者使用不同的标志(只要邮件服务器支持用户标志)。当使用名称空间配置适配器时,`user-flag`属性可用。
### [](#mail-filtering)邮件过滤 ### 邮件过滤
通常,你可能会遇到过滤收到的消息的要求(例如,你希望只读取`Subject`行中具有“ Spring 集成”的电子邮件)。你可以通过将入站邮件适配器与基于表达式的`Filter`连接起来来实现这一点。尽管它会起作用,但这种方法也有缺点。由于在通过入站邮件适配器之后将对消息进行过滤,因此所有此类消息将被标记为已读(`SEEN`)或未读(取决于`should-mark-messages-as-read`属性的值)。然而,在现实中,只有当消息通过筛选条件时,将消息标记为`SEEN`才更有用。这类似于在浏览预览窗格中的所有邮件时查看电子邮件客户端,但仅标记实际打开并读为`SEEN`的邮件。 通常,你可能会遇到过滤收到的消息的要求(例如,你希望只读取`Subject`行中具有“ Spring 集成”的电子邮件)。你可以通过将入站邮件适配器与基于表达式的`Filter`连接起来来实现这一点。尽管它会起作用,但这种方法也有缺点。由于在通过入站邮件适配器之后将对消息进行过滤,因此所有此类消息将被标记为已读(`SEEN`)或未读(取决于`should-mark-messages-as-read`属性的值)。然而,在现实中,只有当消息通过筛选条件时,将消息标记为`SEEN`才更有用。这类似于在浏览预览窗格中的所有邮件时查看电子邮件客户端,但仅标记实际打开并读为`SEEN`的邮件。
...@@ -360,7 +360,7 @@ Spring Integration2.0.4 在`inbound-channel-adapter`和`imap-idle-channel-adapte ...@@ -360,7 +360,7 @@ Spring Integration2.0.4 在`inbound-channel-adapter`和`imap-idle-channel-adapte
另一个合理的问题是,在下一个轮询或空闲事件中会发生什么,或者在重新启动这样的适配器时会发生什么。是否有重复的按摩需要过滤?换句话说,如果在上一次检索中,有五条新消息,只有一条通过了过滤器,那么其他四条会发生什么情况?在下一次投票时,他们会再次通过过滤逻辑还是空闲?毕竟,它们没有被标记为`SEEN`。答案是否定的。由于电子邮件服务器设置并由 Spring 集成邮件搜索过滤器使用的另一个标志(`RECENT`),它们不会受到重复处理。文件夹实现将此标志设置为表示此邮件是此文件夹新建的。也就是说,它是从上次打开这个文件夹开始到达的。换句话说,虽然我们的适配器可能会偷看电子邮件,但它也让电子邮件服务器知道此类电子邮件已被触摸,因此电子邮件服务器应将其标记为`RECENT` 另一个合理的问题是,在下一个轮询或空闲事件中会发生什么,或者在重新启动这样的适配器时会发生什么。是否有重复的按摩需要过滤?换句话说,如果在上一次检索中,有五条新消息,只有一条通过了过滤器,那么其他四条会发生什么情况?在下一次投票时,他们会再次通过过滤逻辑还是空闲?毕竟,它们没有被标记为`SEEN`。答案是否定的。由于电子邮件服务器设置并由 Spring 集成邮件搜索过滤器使用的另一个标志(`RECENT`),它们不会受到重复处理。文件夹实现将此标志设置为表示此邮件是此文件夹新建的。也就是说,它是从上次打开这个文件夹开始到达的。换句话说,虽然我们的适配器可能会偷看电子邮件,但它也让电子邮件服务器知道此类电子邮件已被触摸,因此电子邮件服务器应将其标记为`RECENT`
### [](#mail-tx-sync)事务同步 ### 事务同步
入站适配器的事务同步允许你在事务提交或回滚之后执行不同的操作。你可以通过为轮询的`<inbound-adapter/>`的 poller 或`<imap-idle-inbound-adapter/>`添加`<transactional/>`元素来启用事务同步。即使不涉及“实际”事务,也可以通过使用带有`<transactional/>`元素的`PseudoTransactionManager`来启用此功能。有关更多信息,请参见[事务同步](./transactions.html#transaction-synchronization) 入站适配器的事务同步允许你在事务提交或回滚之后执行不同的操作。你可以通过为轮询的`<inbound-adapter/>`的 poller 或`<imap-idle-inbound-adapter/>`添加`<transactional/>`元素来启用事务同步。即使不涉及“实际”事务,也可以通过使用带有`<transactional/>`元素的`PseudoTransactionManager`来启用此功能。有关更多信息,请参见[事务同步](./transactions.html#transaction-synchronization)
...@@ -418,7 +418,7 @@ public class Mover { ...@@ -418,7 +418,7 @@ public class Mover {
| |要使消息在事务结束后仍可用于操作,*应该-删除-消息*必须设置为“false”。| | |要使消息在事务结束后仍可用于操作,*应该-删除-消息*必须设置为“false”。|
|---|------------------------------------------------------------------------------------------------------------------------------| |---|------------------------------------------------------------------------------------------------------------------------------|
### [](#mail-java-dsl-configuration)使用 Java DSL 配置通道适配器 ### 使用 Java DSL 配置通道适配器
为了在 Java DSL 中配置邮件组件,框架提供了一个`o.s.i.mail.dsl.Mail`工厂,它可以这样使用: 为了在 Java DSL 中配置邮件组件,框架提供了一个`o.s.i.mail.dsl.Mail`工厂,它可以这样使用:
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# R2DBC 支持 # R2DBC 支持
## [](#r2dbc)R2DBC 支持 ## R2DBC 支持
Spring 集成通过使用通过[R2DBC](https://r2dbc.io/)驱动程序对数据库的反应性访问,为接收和发送消息提供了通道适配器。 Spring 集成通过使用通过[R2DBC](https://r2dbc.io/)驱动程序对数据库的反应性访问,为接收和发送消息提供了通道适配器。
...@@ -22,7 +22,7 @@ Gradle ...@@ -22,7 +22,7 @@ Gradle
compile "org.springframework.integration:spring-integration-r2dbc:5.5.9" compile "org.springframework.integration:spring-integration-r2dbc:5.5.9"
``` ```
### [](#r2dbc-inbound-channel-adapter)R2DBC 入站通道适配器 ### R2DBC 入站通道适配器
`R2dbcMessageSource`是一个基于`R2dbcEntityOperations`的 pollable`MessageSource`实现,并生成带有`Flux``Mono`的消息,作为根据`expectSingleResult`选项从数据库中获取数据的有效负载。可以静态地提供对`SELECT`的查询,也可以基于对每个`receive()`调用求值的 SPEL 表达式。`R2dbcMessageSource.SelectCreator`作为求值上下文的根对象存在,以允许使用`StatementMapper.SelectSpec`fluent API。默认情况下,此通道适配器将从 SELECT 映射到`LinkedCaseInsensitiveMap`实例中的记录。可以根据`this.r2dbcEntityOperations.getConverter()`定制提供`payloadType`选项,该选项由`EntityRowMapper`在下面使用。`updateSql`是可选的,用于在数据库中 Mark Read 记录,以便跳过后续的轮询。`UPDATE`操作可以提供一个`BiFunction<DatabaseClient.GenericExecuteSpec, ?, DatabaseClient.GenericExecuteSpec>`,根据`SELECT`结果中的记录,将值绑定到`UPDATE`中。 `R2dbcMessageSource`是一个基于`R2dbcEntityOperations`的 pollable`MessageSource`实现,并生成带有`Flux``Mono`的消息,作为根据`expectSingleResult`选项从数据库中获取数据的有效负载。可以静态地提供对`SELECT`的查询,也可以基于对每个`receive()`调用求值的 SPEL 表达式。`R2dbcMessageSource.SelectCreator`作为求值上下文的根对象存在,以允许使用`StatementMapper.SelectSpec`fluent API。默认情况下,此通道适配器将从 SELECT 映射到`LinkedCaseInsensitiveMap`实例中的记录。可以根据`this.r2dbcEntityOperations.getConverter()`定制提供`payloadType`选项,该选项由`EntityRowMapper`在下面使用。`updateSql`是可选的,用于在数据库中 Mark Read 记录,以便跳过后续的轮询。`UPDATE`操作可以提供一个`BiFunction<DatabaseClient.GenericExecuteSpec, ?, DatabaseClient.GenericExecuteSpec>`,根据`SELECT`结果中的记录,将值绑定到`UPDATE`中。
...@@ -65,7 +65,7 @@ IntegrationFlow r2dbcDslFlow(R2dbcEntityTemplate r2dbcEntityTemplate) { ...@@ -65,7 +65,7 @@ IntegrationFlow r2dbcDslFlow(R2dbcEntityTemplate r2dbcEntityTemplate) {
} }
``` ```
### [](#r2dbc-outbound-channel-adapter)R2DBC 出站通道适配器 ### R2DBC 出站通道适配器
`R2dbcMessageHandler`是一个`ReactiveMessageHandler`实现,用于在数据库中使用提供的`R2dbcEntityOperations`执行`INSERT`(默认)、`UPDATE``DELETE`查询。`R2dbcMessageHandler.Type`可以静态配置,也可以通过针对请求消息的 SPEL 表达式配置。要执行的查询可以基于`tableName``values``criteria`表达式选项,或者(如果不提供`tableName`)将整个消息有效负载作为`org.springframework.data.relational.core.mapping.Table`实体来执行 SQL。将包`org.springframework.data.relational.core.query`注册为导入到 SPEL 评估上下文中,以直接访问`Criteria`Fluent API,该 API 用于`UPDATE``DELETE`查询。`valuesExpression``INSERT``UPDATE`中使用,并且必须对`Map`进行求值,以便对列值对在目标表中执行针对请求消息的更改。 `R2dbcMessageHandler`是一个`ReactiveMessageHandler`实现,用于在数据库中使用提供的`R2dbcEntityOperations`执行`INSERT`(默认)、`UPDATE``DELETE`查询。`R2dbcMessageHandler.Type`可以静态配置,也可以通过针对请求消息的 SPEL 表达式配置。要执行的查询可以基于`tableName``values``criteria`表达式选项,或者(如果不提供`tableName`)将整个消息有效负载作为`org.springframework.data.relational.core.mapping.Table`实体来执行 SQL。将包`org.springframework.data.relational.core.query`注册为导入到 SPEL 评估上下文中,以直接访问`Criteria`Fluent API,该 API 用于`UPDATE``DELETE`查询。`valuesExpression``INSERT``UPDATE`中使用,并且必须对`Map`进行求值,以便对列值对在目标表中执行针对请求消息的更改。
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册