跳到主要内容
版本:7.0.2

Spring ApplicationEvent 支持

DeepSeek V3 中英对照 Spring ApplicationEvent Support Spring ApplicationEvent Support

Spring Integration 为入站和出站 ApplicationEvents 提供了支持,这些事件由底层的 Spring Framework 定义。有关 Spring 对事件和监听器支持的更多信息,请参阅 Spring 参考手册

此依赖项为项目所需:

<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-event</artifactId>
<version>7.0.2</version>
</dependency>

接收 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 ApplicationEvent,请创建一个 ApplicationEventPublishingMessageHandler 实例并在端点中注册它。这个 MessageHandler 接口的实现类也实现了 Spring 的 ApplicationEventPublisherAware 接口,因此它充当了 Spring Integration 消息与 ApplicationEvent 之间的桥梁。

为了方便,命名空间支持通过 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>),使其将 payload 按原样发布到应用上下文中,而不是将其包装到 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 的更多信息,请参阅基于注解的配置部分。