Spring ApplicationEvent
サポート
Spring Integration は、基礎となる Spring Framework で定義されているように、受信および発信 ApplicationEvents
のサポートを提供します。Spring のイベントとリスナーのサポートの詳細については、Spring リファレンスマニュアルを参照してください。
この依存関係をプロジェクトに含める必要があります。
Spring アプリケーションイベントの受信
イベントを受信してチャネルに送信するには、Spring Integration の ApplicationEventListeningMessageProducer
のインスタンスを定義できます。このクラスは、Spring の ApplicationListener
インターフェースの実装です。デフォルトでは、受信したすべてのイベントを Spring Integration メッセージとして渡します。イベントの型に基づいて制限するには、"eventTypes" プロパティを使用して、受信するイベント型のリストを設定できます。受信したイベントに「ソース」として Message
インスタンスがある場合、その Message
はそのまま渡されます。それ以外の場合、SpEL ベースの payloadExpression
が提供されている場合、ApplicationEvent
インスタンスに対して評価されます。イベントのソースが Message
インスタンスではなく、payloadExpression
が提供されていない場合、ApplicationEvent
自体がペイロードとして渡されます。
バージョン 4.2 以降、ApplicationEventListeningMessageProducer
は GenericApplicationListener
を実装し、ApplicationEvent
型だけでなく、ペイロードイベントを処理するための任意の型(Spring Framework 4.2 以降もサポートされています)を受け入れるように構成できます。受け入れられたイベントが PayloadApplicationEvent
のインスタンスである場合、その payload
はメッセージの送信に使用されます。
便宜上、次の例に示すように、ApplicationEventListeningMessageProducer
を inbound-channel-adapter
要素で構成するための名前空間サポートが提供されます。
<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" (オプション)属性で指定された型のいずれかに一致するすべてのアプリケーションコンテキストイベントが、"eventChannel" という名前のメッセージチャネルに Spring Integration メッセージとして配信されます。ダウンストリームコンポーネントが例外をスローすると、失敗したメッセージと例外を含む 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
の間のブリッジとして機能します。
便宜上、次の例に示すように、ApplicationEventPublishingMessageHandler
を outbound-channel-adapter
要素で構成するための名前空間サポートが提供されます。
<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" チャネルに送信されるすべてのメッセージは、同じ Spring ApplicationContext
内に登録されている関連する ApplicationListener
インスタンスに ApplicationEvent
インスタンスとして公開されます。メッセージのペイロードが ApplicationEvent
である場合、そのまま渡されます。それ以外の場合、メッセージ自体は MessagingEvent
インスタンスにラップされます。
バージョン 4.2 から、MessagingEvent
インスタンスにラップする代わりに、publish-payload
ブール属性で ApplicationEventPublishingMessageHandler
(<int-event:outbound-channel-adapter>
)を構成して、アプリケーションコンテキスト payload
にパブリッシュすることができます。
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
の詳細については、"アノテーション主導の構成" セクションを参照してください。