Spring ApplicationEvent
Support
Spring Integration 提供对入站和出站 ApplicationEvents
的支持,如底层的 Spring Framework 所定义。有关 Spring 对事件和侦听器的支持的详细信息,请参见 Spring Reference Manual。
Spring Integration provides support for inbound and outbound ApplicationEvents
, as defined by the underlying Spring Framework.
For more information about Spring’s support for events and listeners, see the Spring Reference Manual.
你需要将此依赖项包含在你的项目中:
You need to include this dependency into your project:
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-event</artifactId>
<version>{project-version}</version>
</dependency>
compile "org.springframework.integration:spring-integration-event:{project-version}"
Receiving Spring Application Events
若要接收事件并将其发送到通道,你可以定义 Spring 集成的 ApplicationEventListeningMessageProducer
实例。此类是 Spring 的 ApplicationListener
接口的实现。默认情况下,它将所有接收到的事件作为 Spring 集成消息传递。若要基于事件类型进行限制,你可以使用 'eventTypes' 属性来配置想要接收的事件类型列表。如果收到的事件将其 Message
实例作为其“来源”,那么该 Message
会按原样传递。否则,如果已提供基于 SpEL 的 payloadExpression
,那么会根据 ApplicationEvent
实例评估该 SpEL。如果该事件的来源不是 Message
实例,并且没有提供 payloadExpression
,那么 ApplicationEvent
本身会作为有效载荷传递。
To receive events and send them to a channel, you can define an instance of Spring Integration’s ApplicationEventListeningMessageProducer
.
This class is an implementation of Spring’s ApplicationListener
interface.
By default, it passes all received events as Spring Integration messages.
To limit based on the type of event, you can use the 'eventTypes' property to configure the list of event types that you want to receive.
If a received event has a Message
instance as its 'source', that Message
is passed as-is.
Otherwise, if a SpEL-based payloadExpression
has been provided, that is evaluated against the ApplicationEvent
instance.
If the event’s source is not a Message
instance and no payloadExpression
has been provided, the ApplicationEvent
itself is passed as the payload.
从版本 4.2 开始,ApplicationEventListeningMessageProducer
实现 GenericApplicationListener
,并且配置为不仅接受 ApplicationEvent
类型,还接受任何用于处理有效载荷事件(Spring Framework 4.2 以来也受支持)的类型。当已接受的事件是 PayloadApplicationEvent
实例时,它的 payload
用于要发送的消息。
Starting with version 4.2, the ApplicationEventListeningMessageProducer
implements GenericApplicationListener
and can be configured to accept not only ApplicationEvent
types but any type for treating payload events (which are also supported since Spring Framework 4.2).
When the accepted event is an instance of PayloadApplicationEvent
, its payload
is used for the message to send.
为方便起见,提供了命名空间支持,可以使用 inbound-channel-adapter
元素配置 ApplicationEventListeningMessageProducer
,如下例所示:
For convenience, namespace support is provided to configure an ApplicationEventListeningMessageProducer
with the inbound-channel-adapter
element, as the following example shows:
<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
且下游通道是同步的,则该异常会传播到调用者。
In the preceding example, all application context events that match one of the types specified by the 'event-types' (optional) attribute are delivered as Spring Integration messages to the message channel named 'eventChannel'.
If a downstream component throws an exception, a MessagingException
that contains the failed message and exception is sent to the channel named 'eventErrorChannel'.
If no error-channel
is specified and the downstream channels are synchronous, the exception is propagated to the caller.
使用 Java 配置相同的适配器:
Using Java to configure the same adapter:
@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:
With the 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();
}
Sending Spring Application Events
若要发送 Spring ApplicationEvents
,请创建 ApplicationEventPublishingMessageHandler
实例并在端点内注册该实例。此 MessageHandler
接口的实现还实现了 Spring 的 ApplicationEventPublisherAware
接口,因此充当 Spring 集成消息和 ApplicationEvents
之间的桥梁。
To send Spring ApplicationEvents
, create an instance of the ApplicationEventPublishingMessageHandler
and register it within an endpoint.
This implementation of the MessageHandler
interface also implements Spring’s ApplicationEventPublisherAware
interface and consequently acts as a bridge between Spring Integration messages and ApplicationEvents
.
为方便起见,提供了命名空间支持,可以使用 outbound-channel-adapter
元素配置 ApplicationEventPublishingMessageHandler
,如下例所示:
For convenience, namespace support is provided to configure an ApplicationEventPublishingMessageHandler
with the outbound-channel-adapter
element, as the following example shows:
<int:channel id="eventChannel"/>
<int-event:outbound-channel-adapter channel="eventChannel"/>
如果使用 PollableChannel
(比如 QueueChannel
),也可以提供 outbound-channel-adapter
元素的 poller
子元素。还可以为那个 poller 可选地提供 task-executor
引用。以下示例展示了这两个操作:
If you use a PollableChannel
(such as a QueueChannel
), you can also provide a poller
child element of the outbound-channel-adapter
element.
You can also optionally provide a task-executor
reference for that poller.
The following example demonstrates both:
<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
实例。如果消息的 payload 是 ApplicationEvent
,则原样传递。否则,消息本身会包装在 MessagingEvent
实例中。
In the preceding example, all messages sent to the 'eventChannel' channel are published as ApplicationEvent
instances to any relevant ApplicationListener
instances that are registered within the same Spring ApplicationContext
.
If the payload of the message is an ApplicationEvent
, it is passed as-is.
Otherwise, the message itself is wrapped in a MessagingEvent
instance.
从 4.2 版本开始,可以使用 publish-payload
布尔属性针对 ApplicationEventPublishingMessageHandler
(<int-event:outbound-channel-adapter>
)进行配置,以按原样发布到应用程序上下文 payload
,而不将其包装到 MessagingEvent
实例中。
Starting with version 4.2, you can configure the ApplicationEventPublishingMessageHandler
(<int-event:outbound-channel-adapter>
) with the publish-payload
boolean attribute to publish to the application context payload
as is, instead of wrapping it to a MessagingEvent
instance.
使用 Java 配置针对适配器进行配置:
To configure the adapter using Java configuration:
@Bean
@ServiceActivator(inputChannel = "eventChannel")
public ApplicationEventPublishingMessageHandler eventHandler() {
ApplicationEventPublishingMessageHandler handler =
new ApplicationEventPublishingMessageHandler();
handler.setPublishPayload(true);
return handler;
}
使用 Java DSL:
With the 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
结合使用:
The @Publisher
annotation also can be used in combination with an @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
的有效负载。有关 Annotation-driven Configuration 部分中 @Publisher
的详细信息,请参见更多信息。
In this case a return value of the event listener method is used as a payload for a Message
to be published to that eventFromPublisher
channel.
See more information about the @Publisher
in the Annotation-driven Configuration section.