上一章中学习了系统监听器模式,这章主要学习系统监听器模式在springboot中是怎样运行的。
1.系统监听器ApplicationListener
首先看一下ApplicationListener类的官方描述:springboot中的监听器是通过实现这个类来监听事件,这个接口是基于监听器标准来设计的,在spring3.0以后,一个监听器可以定义自己感性的事件,当程序运行到一些关键节点的时候,会发出这些事件,并根据对应事件渲染出感兴趣的监听器来触发事件。这个就是ApplicationListener注释的一个描述,接下里,去看下源码是具体怎么实现的。
public interface EventListener {
}
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}
可以看到ApplicationListener继承了EventListener,这个EventListener是个空接口,主要本质是声明实现了这个接口的类都是一个事件监听器。ApplicationListener有一个@FunctionalInterface注解,这个注解是jdk1.8后新增注解,含义是这个接口内只有一个方法。这个接口有一个泛型ApplicationEvent,它的意思是在实现这个接口的时候可以声明你对哪些事件感兴趣,系统再触发事件的时候就可以过滤你对哪些事件感兴趣。这个接口定义了一个方法,当你监听到这个事件的时候去执行什么方法(与上一节我们自己的基本一样)。
2.系统广播器ApplicationEventMulticaster
一样的我们先看一下官方描述:这个接口通常用来管理一堆用户监听器并且广播事件。描述非常简单,那他具体怎么实现的我们还是要看下源码。
public interface ApplicationEventMulticaster {
/**
* Add a listener to be notified of all events.
* @param listener the listener to add
*/
void addApplicationListener(ApplicationListener<?> listener);
/**
* Add a listener bean to be notified of all events.
* @param listenerBeanName the name of the listener bean to add
*/
void addApplicationListenerBean(String listenerBeanName);
/**
* Remove a listener from the notification list.
* @param listener the listener to remove
*/
void removeApplicationListener(ApplicationListener<?> listener);
/**
* Remove a listener bean from the notification list.
* @param listenerBeanName the name of the listener bean to remove
*/
void removeApplicationListenerBean(String listenerBeanName);
/**
* Remove all listeners registered with this multicaster.
* <p>After a remove call, the multicaster will perform no action
* on event notification until new listeners are registered.
*/
void removeAllListeners();
/**
* Multicast the given application event to appropriate listeners.
* <p>Consider using {@link #multicastEvent(ApplicationEvent, ResolvableType)}
* if possible as it provides better support for generics-based events.
* @param event the event to multicast
*/
void multicastEvent(ApplicationEvent event);
/**
* Multicast the given application event to appropriate listeners.
* <p>If the {@code eventType} is {@code null}, a default type is built
* based on the {@code event} instance.
* @param event the event to multicast
* @param eventType the type of event (can be {@code null})
* @since 4.2
*/
void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);
}
从源码可以看到,它主要有三个方法:添加监听器,删除监听器,广播监听器。
3.系统事件介绍SpringApplicationEvent
它主要是描述某一类的事件的发生,这里对于系统事件进行一个简单描述:SpringApplicationEvent继承自ApplicationEvent,而ApplicationEvent又继承自EventObject。这代表了一个流向:对象事件->应用事件->springboot应用事件,它有子类实现,比如说ApplicationStartingEvent系统启动事件,ApplicationFailedEvent系统启动失败事件等等。这里就不做过多描述,我们主要来了解下事件发生顺序。
- 框架启动
- starting
- environmentPrepared
- contextInitialized
- prepared
- started
- ready
- 启动完毕
这个是springboot正常启动发送事件的一个顺序,如果框架启动失败则发送failed事件。文字描述就是:框架在一启动的时候会发送一个starting事件,在环境准备好之后会发送一个environmentPrepared事件,代表我们环境已经准备好了,接下里会发送contextInitialized事件,代表springboot已经启动准备好了上下文,是在我们加载任何bean之前发送的,接下来会发送一个prepared事件,代表我们应用上下文已经创建完毕,但bean还没有加载完成,接着调用started事件,代表我们bean已经实例化完成了,但还没有调用ApplicationRunner和CommandLineRunner这两个扩展接口,接着发送ready事件代表我们已经调用了那两个扩展接口。如果启动过程失败就会发送failed事件。这个就是我们springboot事件的发生顺序。