ApplicationListener接口只有一个onApplicationEvent方法,用来处理applicationEvent(观察者模式)
在分析springboot中的事件监听加载与运行之前,先简单介绍下Spring事件体系,方便后面更好的理解springboot的事件监听。
一、Spring事件体系,主要由事件ApplicationEvent、监听器ApplicationListener、事件源ApplicationContext组成。
1.ApplicationEvent
public abstract class ApplicationEvent extends EventObject { public ApplicationEvent(Object source) { super(source); this.timestamp = System.currentTimeMillis(); } }
继承JDK的EventObject,其中source表示事件源;ApplicationEvent的实现类ApplicationContextEvent表示容器事件,对应的事件源是ApplicationContext(Spring容器)。
2.ApplicationListener
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { void onApplicationEvent(E event); }
继承JDK的EventListener(JDK注释所有的监听都应该继承EventListener),只有一个onApplication方法,该方法接收一个ApplicationEvent参数,根据不同的事件类型做不同处理。当事件触发时监听器会收到事件消息,并根据消息类型进行对应的处理,如果有多个消息监听器,会按照指定的顺序依次收到消息。
3.ApplicationContext
Spring容器,也是Spring体系中的事件源。该类继承了ApplicationEventPublisher接口,publishEvent(ApplicationEvent event)方法,当事件触发时,通过调用该方法进行事件发布,所有的ApplicationListener就是收到事件消息。
ApplicationContext的抽象实现类AbstractApplicationContext实现了publishEvent方法。
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { public void publishEvent(ApplicationEvent event) { publishEvent(event, null); } public void publishEvent(Object event) { publishEvent(event, null); } protected void publishEvent(Object event, @Nullable ResolvableType eventType) { Assert.notNull(event, "Event must not be null"); // Decorate event as an ApplicationEvent if necessary ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { applicationEvent = new PayloadApplicationEvent<>(this, event); if (eventType == null) { eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType(); } } // Multicast right now if possible - or lazily once the multicaster is initialized if (this.earlyApplicationEvents != null) { this.earlyApplicationEvents.add(applicationEvent); } else { getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); } // Publish event via parent context as well... if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } } } }
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
事件的发布是通过ApplicationEventMulticaster进行事件广播。
4.ApplicationEventMulticaster
事件广播器,作用是将ApplicationContext发布的事件广播给监听器ApplicationListener。其中定义的主要方法有:注册监听器、移除监听器和广播事件
其抽象继承类AbstractApplicationEventMulticaster只实现了注册和移除监听器方法;SimpleApplicationEventMulticaster继承自AbstractApplicationEventMulticaster,实现了广播事件方法。
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster { @Override public void multicastEvent(ApplicationEvent event) { multicastEvent(event, resolveDefaultEventType(event)); } @Override public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) { ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)); for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) { Executor executor = getTaskExecutor(); if (executor != null) { executor.execute(() -> invokeListener(listener, event)); } else { invokeListener(listener, event); } } } }
invokeListener(listener, event)方法,会调用listener.onApplicationEvent(event); 也就是事件广播的本质就是调用所有的监听器的onApplicationEvent方法。
二、ApplicationListener加载与运行