Spring ApplicationEvent 支持

SpringApplicationEvent支持

Spring 集成提供对入站和出站的支持ApplicationEvents,由底层 Spring 框架定义。 有关 Spring 对事件和侦听器的支持的更多信息,请参见 Spring 参考手册spring-doc.cadn.net.cn

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

Maven 系列
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-event</artifactId>
    <version>6.0.9</version>
</dependency>
Gradle
compile "org.springframework.integration:spring-integration-event:6.0.9"

接收 Spring 应用程序事件

要接收事件并将其发送到通道,您可以定义 Spring Integration 的ApplicationEventListeningMessageProducer. 这个类是 Spring 的ApplicationListener接口。 默认情况下,它将所有收到的事件作为 Spring 集成消息传递。 要根据事件类型进行限制,您可以使用 'eventTypes' 属性来配置要接收的事件类型列表。 如果收到的事件具有Message实例作为其 'source',则Message按原样传递。 否则,如果基于 SPEL 的payloadExpression,该 API 将根据ApplicationEvent实例。 如果事件的源不是Messageinstance 和 nopayloadExpression,则ApplicationEvent本身作为 payload 传递。spring-doc.cadn.net.cn

从版本 4.2 开始,ApplicationEventListeningMessageProducer实现GenericApplicationListener并且不仅可以配置为接受ApplicationEvent类型,但任何类型都用于处理有效负载事件(从 Spring Framework 4.2 开始也支持)。 当 accepted 事件是PayloadApplicationEventpayload用于发送消息。spring-doc.cadn.net.cn

为方便起见,提供了命名空间支持来配置ApplicationEventListeningMessageProducer使用inbound-channel-adapter元素,如下例所示: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 集成消息传送到名为'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 应用程序事件

发送 SpringApplicationEvents中,创建ApplicationEventPublishingMessageHandler并在终端节点中注册它。 此MessageHandler接口还实现了 Spring 的ApplicationEventPublisherAware接口,因此充当 Spring 集成消息和ApplicationEvents.spring-doc.cadn.net.cn

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

<int:channel id="eventChannel"/>

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

如果您使用PollableChannel(例如QueueChannel),您还可以提供poller子元素的outbound-channel-adapter元素。 您还可以选择提供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实例添加到任何相关的ApplicationListener在同一个 Spring 中注册的实例ApplicationContext. 如果消息的有效负载是ApplicationEvent,则按原样传递。 否则,消息本身将包装在MessagingEvent实例。spring-doc.cadn.net.cn

从版本 4.2 开始,您可以配置ApplicationEventPublishingMessageHandler (<int-event:outbound-channel-adapter>) 替换为publish-payloadboolean 属性发布到应用程序上下文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);
}