如需使用最新稳定版本,请使用 Spring Integration 7.0.4spring-doc.cadn.net.cn

Spring ApplicationEvent 支持

Spring Integration 提供了对底层 Spring Framework 定义的双向 ApplicationEvents 的支持。 有关 Spring 对事件和监听器的支持的更多信息,请参阅 Spring 参考手册spring-doc.cadn.net.cn

您需要将以下依赖项包含到您的项目中:spring-doc.cadn.net.cn

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-event</artifactId>
    <version>6.4.10</version>
</dependency>
compile "org.springframework.integration:spring-integration-event:6.4.10"

接收 Spring 应用程序事件

要接收事件并将其发送到通道,您可以定义 Spring Integration 的 ApplicationEventListeningMessageProducer 实例。 该类是 Spring 的 ApplicationListener 接口的实现。 默认情况下,它会将所有接收到的事件作为 Spring Integration 消息传递。 若要基于事件类型进行限制,您可以使用 'eventTypes' 属性来配置您希望接收的事件类型列表。 如果接收到的事件的 'source' 为 Message 实例,则该 Message 将原样传递。 否则,如果提供了基于 SpEL 的 payloadExpression,则将对 ApplicationEvent 实例对其进行求值。 如果事件的 source 不是 Message 实例且未提供 payloadExpression,则将 ApplicationEvent 本身作为负载传递。spring-doc.cadn.net.cn

从版本 4.2 开始,ApplicationEventListeningMessageProducer 实现了 GenericApplicationListener,并且可以配置为不仅接受 ApplicationEvent 类型,还可以接受任何类型来处理负载事件(这些功能自 Spring Framework 4.2 起也已支持)。 当所接受的事件是 PayloadApplicationEvent 的实例时,将使用其 payload 作为要发送的消息。spring-doc.cadn.net.cn

为方便起见,提供了命名空间支持,以便使用 inbound-channel-adapter 元素配置 ApplicationEventListeningMessageProducer,如下示例所示:spring-doc.cadn.net.cn

<int-event:inbound-channel-adapter channel="eventChannel"
                                   error-channel="eventErrorChannel"
                                   event-types="example.FooEvent, example.BarEvent, java.util.Date"/>

<int:publish-subscribe-channel id="eventChannel"/>

在前面的示例中,所有与 'event-types'(可选)属性指定的类型之一匹配的应用程序上下文事件,都会作为 Spring Integration 消息发送到名为 'eventChannel' 的消息通道。 如果下游组件抛出异常,则包含失败消息和异常的 MessagingException 会被发送到名为 'eventErrorChannel' 的通道。 如果未指定 error-channel 且下游通道是同步的,则异常会传播给调用者。spring-doc.cadn.net.cn

使用 Java 配置相同的适配器:spring-doc.cadn.net.cn

@Bean
public ApplicationEventListeningMessageProducer eventsAdapter(
            MessageChannel eventChannel, MessageChannel eventErrorChannel) {

    ApplicationEventListeningMessageProducer producer =
        new ApplicationEventListeningMessageProducer();
    producer.setEventTypes(example.FooEvent.class, example.BarEvent.class, java.util.Date.class);
    producer.setOutputChannel(eventChannel);
    producer.setErrorChannel(eventErrorChannel);
    return producer;
}

使用 Java DSL:spring-doc.cadn.net.cn

@Bean
public ApplicationEventListeningMessageProducer eventsAdapter() {

    ApplicationEventListeningMessageProducer producer =
        new ApplicationEventListeningMessageProducer();
    producer.setEventTypes(example.FooEvent.class, example.BarEvent.class, java.util.Date.class);
    return producer;
}

@Bean
public IntegrationFlow eventFlow(ApplicationEventListeningMessageProducer eventsAdapter,
        MessageChannel eventErrorChannel) {

    return IntegrationFlow.from(eventsAdapter, e -> e.errorChannel(eventErrorChannel))
        .handle(...)
        ...
        .get();
}

发送 Spring 应用事件

要发送 Spring ApplicationEvents,请创建 ApplicationEventPublishingMessageHandler 的实例并在端点中注册它。 该 MessageHandler 接口的实现同时也实现了 Spring 的 ApplicationEventPublisherAware 接口,因此充当 Spring Integration 消息与 ApplicationEvents 之间的桥梁。spring-doc.cadn.net.cn

为方便起见,提供了命名空间支持,以便使用 outbound-channel-adapter 元素配置 ApplicationEventPublishingMessageHandler,如下示例所示:spring-doc.cadn.net.cn

<int:channel id="eventChannel"/>

<int-event:outbound-channel-adapter channel="eventChannel"/>

如果您使用 PollableChannel(例如 QueueChannel),您还可以为 outbound-channel-adapter 元素提供一个 poller 子元素。 您还可以为该轮询器可选地提供一个 task-executor 引用。 以下示例同时演示了这两种情况:spring-doc.cadn.net.cn

<int:channel id="eventChannel">
  <int:queue/>
</int:channel>

<int-event:outbound-channel-adapter channel="eventChannel">
  <int:poller max-messages-per-poll="1" task-executor="executor" fixed-rate="100"/>
</int-event:outbound-channel-adapter>

<task:executor id="executor" pool-size="5"/>

在上面的示例中,发送到 'eventChannel' 通道的所有消息都会作为 ApplicationEvent 实例发布到同一 Spring ApplicationContext 内注册的任何相关 ApplicationListener 实例。 如果消息的负载是 ApplicationEvent,则原样传递。 否则,消息本身会被包装在 MessagingEvent 实例中。spring-doc.cadn.net.cn

从版本 4.2 开始,您可以使用 publish-payload 布尔属性配置 ApplicationEventPublishingMessageHandler<int-event:outbound-channel-adapter>),以便将其实例直接发布到应用上下文 payload,而无需将其包装为 MessagingEvent 实例。spring-doc.cadn.net.cn

使用 Java 配置来设置适配器:spring-doc.cadn.net.cn

@Bean
@ServiceActivator(inputChannel = "eventChannel")
public ApplicationEventPublishingMessageHandler eventHandler() {
    ApplicationEventPublishingMessageHandler handler =
            new ApplicationEventPublishingMessageHandler();
    handler.setPublishPayload(true);
    return handler;
}

使用 Java DSL:spring-doc.cadn.net.cn

@Bean
public ApplicationEventPublishingMessageHandler eventHandler() {
    ApplicationEventPublishingMessageHandler handler =
            new ApplicationEventPublishingMessageHandler();
    handler.setPublishPayload(true);
    return handler;
}

@Bean
// MessageChannel is "eventsFlow.input"
public IntegrationFlow eventsOutFlow(ApplicationEventPublishingMessageHandler eventHandler) {
    return f -> f.handle(eventHandler);
}

@Publisher 注解也可以与 @EventListener 结合使用:spring-doc.cadn.net.cn

@Configuration
@EnableIntegration
@EnablePublisher
public static class ContextConfiguration {

     @Bean
     QueueChannel eventFromPublisher() {
         return new QueueChannel();
     }

     @EventListener
     @Publisher("eventFromPublisher")
     public String publishEventToChannel(TestApplicationEvent3 testApplicationEvent3) {
         return testApplicationEvent3.getSource().toString();
     }

}

在这种情况下,事件监听器方法的返回值将用作 Message 的负载,并发布到该 eventFromPublisher 通道。 有关 @Publisher 的更多信息,请参阅 基于注解的配置 部分。spring-doc.cadn.net.cn