Spring ApplicationEvent 支援
Spring Integration 為入站和出站 ApplicationEvents 提供支援,這些事件由底層 Spring Framework 定義。有關 Spring 對事件和監聽器支援的更多資訊,請參閱 Spring 參考手冊。
專案需要此依賴項
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-event</artifactId>
<version>7.0.0</version>
</dependency>
compile "org.springframework.integration:spring-integration-event:7.0.0"
接收 Spring Application 事件
要接收事件並將其傳送到通道,您可以定義 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 Application 事件
要傳送 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>),以將應用程式上下文 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 通道的訊息的有效負載。有關 @Publisher 的更多資訊,請參閱 註解驅動配置 部分。