Spring ApplicationEvent 支持

Spring Integration 提供对入站和出站ApplicationEvents的支持,正如底层 Spring 框架所定义的那样。有关 Spring 对事件和监听器的支持的更多信息,请参见Spring 参考手册

您需要将此依赖项包含到您的项目中

  • Maven

  • Gradle

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

接收 Spring 应用事件

要接收事件并将它们发送到通道,您可以定义 Spring Integration 的ApplicationEventListeningMessageProducer实例。此类是 Spring 的ApplicationListener接口的实现。默认情况下,它将所有接收到的事件作为 Spring Integration 消息传递。要根据事件类型进行限制,您可以使用“eventTypes”属性配置要接收的事件类型列表。如果接收到的事件的“source”是Message实例,则按原样传递该Message。否则,如果已提供基于 SpEL 的payloadExpression,则会针对ApplicationEvent实例对其进行评估。如果事件的源不是Message实例并且未提供payloadExpression,则ApplicationEvent本身将作为有效负载传递。

从 4.2 版开始,ApplicationEventListeningMessageProducer实现了GenericApplicationListener,并且可以配置为不仅接受ApplicationEvent类型,还可以接受任何类型来处理有效负载事件(自 Spring Framework 4.2 起也支持)。当接受的事件是PayloadApplicationEvent的实例时,其payload将用于要发送的消息。

为方便起见,命名空间支持用于使用inbound-channel-adapter元素配置ApplicationEventListeningMessageProducer,如下例所示

<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并且下游通道是同步的,则异常将传播到调用者。

使用 Java 配置相同的适配器

@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

@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之间的桥梁。

为方便起见,命名空间支持用于使用outbound-channel-adapter元素配置ApplicationEventPublishingMessageHandler,如下例所示

<int:channel id="eventChannel"/>

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

如果使用PollableChannel(例如QueueChannel),还可以提供outbound-channel-adapter元素的poller子元素。您还可以选择为此轮询器提供task-executor引用。以下示例演示两者

<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实例中。

从 4.2 版开始,您可以使用publish-payload布尔属性配置ApplicationEventPublishingMessageHandler<int-event:outbound-channel-adapter>),以便按原样将有效负载发布到应用程序上下文,而不是将其包装到MessagingEvent实例中。

使用 Java 配置配置适配器

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

使用 Java DSL

@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结合使用

@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();
     }

}

在这种情况下,事件监听器方法的返回值用作要发布到该eventFromPublisher通道的Message的有效负载。有关@Publisher的更多信息,请参见基于注解的配置部分。