1.概述

在本文中,我们将学习Spring框架提供的事件支持机制。

我们将探索框架提供的各种内置事件,然后查看如何使用事件。

要了解有关创建和发布自定义事件,请看Spring 自定义事件

Spring具有围绕ApplicationContext构建的事件机制 。

它可用于在不同bean之间交换信息。

我们可以通过监听事件并执行自定义代码来利用应用程序事件。

比如,在ApplicationContext的完全启动时执行自定义初始化。

2. Spring标准上下文事件

Spring中有各种内置事件,使的开发人员可以进入应用程序和上下文的生命周期并执行一些自定义操作。

即使我们很少在应用程序中手动使用这些事件,但Spring框架在其内部大量使用它。

下面来看一下Spring中的各种内置事件。

2.1 ContextRefreshedEvent

在初始化或刷新ApplicationContext时,Spring会发布ContextRefreshedEvent事件。

一般来说,只要尚未关闭上下文,刷新就可以触发。

当然我们也可以通过在ConfigurableApplicationContext接口上调用*refresh()*方法来手动触发事件。

2.2 ContextStartedEvent

ConfigurableApplicationContext上调用*start()*方法,我们触发此事件并启动ApplicationContext

实际上,该方法通常用于在显式停止后重新启动Bean。

我们还可以使用该方法来处理无需配置即可自动启动的组件。

需要注意的是,对start()的调用始终是显式的,与refresh()相反

2.3 ContextStoppedEvent

通过在ConfigurableApplicationContext上调用stop()方法,在停止ApplicationContext时发布ContextStoppedEvent。 当然,我们可以使用start()方法重新启动已停止的事件。

2.4 ContextClosedEvent

当使用ConfigurableApplicationContext中的close()方法关闭ApplicationContext时,将发布此事件。

在关闭应用程序上下文后,我们将无法重新启动它。

应用程序上下文在关闭时就已经寿终正寝了,我们无法像在ContextStoppedEvent中那样重新启动它。

3. @EventListener

下面,让我们探讨如何监听已发布的事件。

从Spring 4.2版本开始,Spring支持注解驱动的事件监听器 @EventListener

我们可以利用此注解基于方法的签名自动注册ApplicationListener

@Component
public class SpringApplicationContextEvents {

    @EventListener
    public void handleContextRefreshEvent(ContextRefreshedEvent ctxRefreshedEvt) {
        System.out.println("ripjava.com: Context Refreshed Event received.");
    }
}

@EventListener是核心注释,因此不需要任何额外的配置。

如果由于处理另一个事件而需要发布一个事件,则可以更改方法签名以返回应发布的事件。

@EventListener
public ListUpdateEvent handleBlackListEvent(BlackListEvent event) {
	  // ....
}

需要注意的是,这种方式不支持异步的监听器。

3.1 监听多个事件

在某些情况下,我们可能需要使用一个监听器监听多个事件。

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

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

4. 监听器

如果使用的是Spring的早期版本(<4.2),则必须实现ApplicationEventListener接口,

并实现onApplicationEvent 方法以监听事件。具体可以参考这篇教程

5. 总结

在本文中,我们探讨了Spring中的各种内置事件。并简单的介绍了@EventListener注解的使用方法