Spring ApplicationEvent
支持
Spring Integration 支持入站和出站 ApplicationEvents
,这由底层的 Spring Framework 定义。有关 Spring 对事件和监听器的支持的更多信息,请参阅 Spring 参考手册。
你需要将此依赖添加到你的项目中
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-event</artifactId>
<version>6.4.4</version>
</dependency>
compile "org.springframework.integration:spring-integration-event:6.4.4"
接收 Spring Application Events
要接收事件并将其发送到通道,你可以定义 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
将用于发送消息。
为了方便起见,提供了 namespace 支持,可以使用 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 Application Events
要发送 Spring ApplicationEvents
,请创建 ApplicationEventPublishingMessageHandler
的实例并在端点内注册它。这个 MessageHandler
接口的实现也实现了 Spring 的 ApplicationEventPublisherAware
接口,因此充当了 Spring Integration 消息和 ApplicationEvents
之间的桥梁。
为了方便起见,提供了 namespace 支持,可以使用 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
的更多信息,请参阅注解驱动的配置部分。