Springboot中监听器属于事件发布机制范畴,其中角色包含:发布者、事件、监听者。
- 监听器Listener:SpringApplicationRunListener & ApplicationListener。用于处理发布者发布的事件。
- 发布者:ApplicationEventPublisher & ApplicationEventMulticaster。
- 事件:ApplicationEvent。
监听器贯穿在Springboot框架整个生命周期内:
- 阶段1:容器刷新之前。
- 阶段2:容器刷新完毕之前的监听机制。
- 阶段3:容器刷新完毕之后的监听机制
1.不同阶段的监听器
public abstract class AbstractApplicationContext{
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		...
		// 阶段二
		initApplicationEventMulticaster();
		// 阶段二:主要初始化 WebServer
		onRefresh();
		// 阶段二:earlyApplicationEvents类型的事件
		registerListeners();
		// Instantiate all remaining (non-lazy-init) singletons.
		finishBeanFactoryInitialization(beanFactory);
		// 阶段三
		finishRefresh();
	}	
}1.1.阶段1之SpringApplicationRunListener
EventPublishingRunListener作为该监听器唯一的实现类是通过SPI机制从META-INF/spring.factories文件中加载得到的。
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
    // ApplicationEventMulticaster 类型的发布器
	private final SimpleApplicationEventMulticaster initialMulticaster;
	public EventPublishingRunListener(SpringApplication application, String[] args) {
		this.application = application;
		this.args = args;
		this.initialMulticaster = new SimpleApplicationEventMulticaster();
	}
}该监听器贯穿在SpringBoot应用启动过程中不同的阶段,每个阶段会触发不同的ApplicationEvent。例如:ApplicationStartingEvent、ApplicationEnvironmentPreparedEvent、ApplicationContextInitializedEvent、ApplicationPreparedEvent等。
1.2.阶段2之earlyApplicationEvents
该阶段是为应用上下文ApplicationContext初始化ApplicationEventMulticaster类型的发布者,区别于阶段1之SpringApplicationRunListener内部的发布者ApplicationEventMulticaster。
public abstract class AbstractApplicationContext{
	// 此时该集合属性中的ApplicationListener 为 SPI机制获取的监听器
	private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
    
    private ApplicationEventMulticaster applicationEventMulticaster;
	private Set<ApplicationEvent> earlyApplicationEvents;
	protected void registerListeners() {
		// 将已知的监听器添加到ApplicationContext中的发布者 ApplicationEventMulticaster
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}
		// 从即将被IOC容器托管的众多类中获取 ApplicationListener类型的BeanNames ~ 注意此时尚未初始化ioc容器
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}
		// 如果集合earlyApplicationEvents存在ApplicationEvent元素
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				//利用 ApplicationContext中ApplicationEventMulticaster持有的全部监听器尝试发送集合earlyEventsToProcess中全部事件
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}
	public Collection<ApplicationListener<?>> getApplicationListeners() {
		return this.applicationListeners;
	}
}从上述伪代码分析得知:该阶段的监听器完全作用于应用上下文ApplicationContext。
在该阶段之前任何时候由发布者ApplicationContext发布的所有事件都被作为集合earlyApplicationEvents中的元素,并在此时由ApplicationContext持有的applicationEventMulticaster来触发全部的监听器处理集合earlyApplicationEvents中全部事件。
1.3.阶段3
该阶段的事件即为容器刷新完毕之后发生的事件。
public abstract class AbstractApplicationContext{
	protected void finishRefresh() {
		initLifecycleProcessor();
		// Propagate refresh to lifecycle processor first.
		getLifecycleProcessor().onRefresh();
		// Publish the final event.
		publishEvent(new ContextRefreshedEvent(this));
		...
	}
}其中,Lifecycle内部会触发ServletWebServerInitializedEvent类型的事件。
2.ApplicationListener
该类型的监听器获取存在两种形式:spring.factories文件 & 监听器Listener以bean形式被ioc容器管理并获取。
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
	void onApplicationEvent(E event);
}如上所示监听器处理 ApplicationEvent 的核心方法。
public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
	boolean supportsEventType(Class<? extends ApplicationEvent> eventType);
	default boolean supportsSourceType(@Nullable Class<?> sourceType) {
		return true;
	}
}如果使用方直接实现接口ApplicationListener,则意味着需要处理所有的ApplicationEvent,包含框架自身出发的事件以及用户自定义Publisher触发的事件。
通常自定义的监听器直接实现SmartApplicationListener or GenericApplicationListener接口,好处是可以根据ApplicationEvent类型 or source类型过滤掉非关注的事件。
2.发布者
2.1.ApplicationEventPublisher
以ApplicationEventPublisherAware为例:
这种Aware类型的接口是被ApplicationContextAwareProcessor后置处理器触发回调的。
public interface ApplicationEventPublisherAware extends Aware {
	void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher);
}注意此时发布者applicationEventPublisher类型为 ApplicationContext。
public abstract class AbstractApplicationContext{
	private Set<ApplicationEvent> earlyApplicationEvents;
	public void publishEvent(Object event) {
		publishEvent(event, null);
	}
	protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
		ApplicationEvent applicationEvent;
		if (event instanceof ApplicationEvent) {
			applicationEvent = (ApplicationEvent) event;
		}else {
			...
		}
		//此时由于处于 所有bean实例化、初始化阶段,此时属性 earlyApplicationEvents 被提前置为空
		if (this.earlyApplicationEvents != null) {
			this.earlyApplicationEvents.add(applicationEvent);
		}else {
			// ApplicationEventPublisherAware 触发的事件,由关注 事件类型eventType 的监听器负责处理
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
		}
		...
	}
}用户自定义一个对eventType事件类型感兴趣的监听器ApplicationListener,并处理该事件。
2.2.ApplicationEventMulticaster
通过上述章节分析得知:该类型的Publisher只是适用于SpringApplicationRunListener、ApplicationContext内部。
当前发布者发布的事件涉及哪些监听器:
- 阶段一:META-INF/spring.factories文件中内置的ApplicationListener。
- 阶段二:除了阶段一,还包括用户自定义被IOC托管的监听器。
3.ApplicationEvent
public abstract class ApplicationEvent extends EventObject {
	public ApplicationEvent(Object source) {
		super(source);
		this.timestamp = System.currentTimeMillis();
	}
}其中,source代表用户传递的数据。










