Spring Application Context Events – Spring应用上下文事件

最后修改: 2018年 8月 29日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

In this tutorial, we’ll learn about the event support mechanism provided by the Spring framework. We’ll explore the various built-in events provided by the framework and then see how to consume an event.

在本教程中,我们将了解Spring框架所提供的事件支持机制。我们将探索框架所提供的各种内置事件,然后看看如何消费一个事件。

To learn about creating and publishing custom events, have a look at our previous tutorial here.

要学习创建和发布自定义事件,请看我们以前的教程

Spring has an eventing mechanism which is built around the ApplicationContext. It can be used to exchange information between different beans. We can make use of application events by listening for events and executing custom code.

Spring有一个围绕ApplicationContext建立的事件机制。它可以用来在不同的Bean之间交换信息。我们可以通过监听事件和执行自定义代码来利用应用程序事件。

For example, a scenario here would be to execute custom logic on the complete startup of the ApplicationContext.

例如,这里的一个场景是在ApplicationContext的完全启动时执行自定义逻辑。

2. Standard Context Events

2.标准上下文事件

In fact, there’re a variety of built-in events in Spring, that lets a developer hook into the lifecycle of an application and the context and do some custom operation.

事实上,Spring中有各种内置的事件,让开发者可以钩住应用程序的生命周期和上下文,进行一些自定义操作。

Even though we rarely use these events manually in an application, the framework uses it intensively within itself. Let’s start by exploring various built-in events in Spring.

尽管我们很少在应用程序中手动使用这些事件,但框架内部却密集地使用它。让我们从探索Spring的各种内置事件开始。

2.1. ContextRefreshedEvent

2.1.ContextRefreshedEvent

On either initializing or refreshing the ApplicationContext, Spring raises the ContextRefreshedEvent. Typically a refresh can get triggered multiple times as long as the context has not been closed.

初始化或刷新ApplicationContext时,Spring会引发ContextRefreshedEvent。通常情况下,只要上下文没有被关闭,刷新就会被多次触发。

Notice that, we can also have the event triggered manually by calling the refresh() method on the ConfigurableApplicationContext interface.

注意,我们也可以通过调用ConfigurableApplicationContext接口的refresh()方法来手动触发事件。

2.2. ContextStartedEvent

2.2.ContextStartedEvent

By calling the start() method on the ConfigurableApplicationContext, we trigger this event and start the ApplicationContext. As a matter of fact, the method is typically used to restart beans after an explicit stop. We can also use the method to deal components with no configuration for autostart.

通过在ConfigurableApplicationContext上调用start()方法,我们触发该事件并启动ApplicationContext。事实上,该方法通常用于在明确停止后重新启动Bean。我们也可以使用该方法来处理没有配置的自动启动的组件。

Here, it’s important to note that the call to start() is always explicit as opposed to refresh().

在这里,需要注意的是,相对于refresh()而言,对start()的调用总是显式的。

2.3. ContextStoppedEvent

2.3.ContextStoppedEvent

A ContextStoppedEvent is published when the ApplicationContext is stopped, by invoking the stop() method on the ConfigurableApplicationContext. As discussed earlier, we can restart a stopped event by using start() method.

ContextStoppedEvent 通过调用ConfigurableApplicationContext>上的stop()方法,ApplicationContext被停止时发布。如前所述,我们可以通过使用start()方法来重新启动一个已停止的事件。

2.4. ContextClosedEvent

2.4.ContextClosedEvent

This event is published when the ApplicationContext is closed, using the close() method in ConfigurableApplicationContext.
In reality, after closing a context, we cannot restart it.

ApplicationContext被关闭时,使用ConfigurableApplicationContext中的close()方法,该事件被发布。
在现实中,关闭一个上下文后,我们不能重新启动它。

A context reaches its end of life on closing it and hence we cannot restart it like in a ContextStoppedEvent.

上下文在关闭时达到其生命的终点,因此我们不能像在ContextStoppedEvent.中那样重新启动它。

3. @EventListener

3.@EventListener

Next, let us explore how to consume the published events. Starting from version 4.2, Spring supports an annotation-driven event listener – @EventListener.

接下来,让我们探讨如何消费已发布的事件。从4.2版本开始,Spring支持一个注解驱动的事件监听器–@EventListener.

In particular, we can make use of this annotation to automatically register an ApplicationListener based on the signature of the method :

特别是,我们可以利用这个注解来基于方法的签名自动注册一个ApplicationListener

@EventListener
public void handleContextRefreshEvent(ContextStartedEvent ctxStartEvt) {
    System.out.println("Context Start Event received.");
}

Significantly, @EventListener is a core annotation and hence doesn’t need any extra configuration. In fact, the existing <context:annotation-driven/> element provides full support to it.

重要的是,@EventListener是一个核心注解,因此不需要任何额外的配置。事实上,现有的<context:annotation-driven/>元素为它提供了全面的支持。

A method annotated with @EventListener can return a non-void type. If the value returned is non-null, the eventing mechanism will publish a new event for it.

@EventListener注解的方法可以返回一个非空类型。如果返回的值是非空的,事件处理机制将为其发布一个新的事件。

3.1. Listening to Multiple Events

3.1.监听多个事件

Now, there might arise situations where we will need our listener to consume multiple events.

现在,可能会出现这样的情况,我们需要我们的监听器来消费多个事件。

For such a scenario, we can make use of classes attribute:

对于这种情况,我们可以利用classes属性。

@EventListener(classes = { ContextStartedEvent.class, ContextStoppedEvent.class })
public void handleMultipleEvents() {
    System.out.println("Multi-event listener invoked");
}

4. Application Event Listener

4.应用程序事件监听器

If we’re using earlier versions of Spring (<4.2), we’ll have to introduce a custom ApplicationEventListener and override the method onApplicationEvent to listen to an event.

如果我们使用早期版本的Spring(<4.2),我们必须引入一个自定义的ApplicationEventListener并重载onApplicationEvent 方法来监听事件。

5. Conclusion

5.结论

In this article, we’ve explored the various built-in events in Spring. In addition, we’ve seen various ways to listen to the published events.

在这篇文章中,我们已经探讨了Spring中的各种内置事件。此外,我们还看到了监听已发布事件的各种方法。

As always, the code snippets used in the article can be found over on Github.

一如既往,文章中使用的代码片段可以在Github上找到over