3.6 ApplicationListener加载
完成了ApplicationContextInitializer的加载之后,便会进行ApplicationListener的加载。它的常见应用场景为:当容器初始化完成之后,需要处理一些如数据的加载、初始化缓存、特定任务的注册等操作。而在此阶段,更多的是用于ApplicationContext管理Bean过程的场景。
Spring事件传播机制是基于观察者模式(Observer)实现的。比如,在ApplicationContext管理Bean生命周期的过程中,会将一些改变定义为事件(ApplicationEvent)。ApplicationContext通过ApplicationListener监听ApplicationEvent,当事件被发布之后,ApplicationListener用来对事件做出具体的操作。
ApplicationListener的整个配置和加载流程与ApplicationContextInitializer完全一致,也是先通过SpringFactoriesLoader的loadFactoryNames方法获得META-INF/spring.factories中对应配置,然后再进行实例化,最后将获得的结果集合添加到SpringApplication的成员变量listeners中,代码如下。
private List<ApplicationListener<?>> listeners; public void setListeners(Collection<? extends ApplicationListener<?>> listeners) { this.listeners = new ArrayList<>(listeners); }
同样的,在调用setListeners方法时也会进行覆盖赋值的操作,之前加载的内容会被清除。
下面我们看看ApplicationListener这里的基本使用。ApplicationListener接口和ApplicationEvent类配合使用,可实现ApplicationContext的事件处理。如果容器中存在ApplicationListener的Bean,当ApplicationContext调用publishEvent方法时,对应的Bean会被触发。这就是上文提到的观察者模式的实现。
在接口ApplicationListener中只定义了一个onApplicationEvent方法,当监听事件被触发时,onApplicationEvent方法会被执行,接口ApplicationListener的源代码如下。
@FunctionalInterface public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { void onApplicationEvent(E event); }
onApplicationEvent方法一般用于处理应用程序事件,参数event为ApplicationEvent的子类,是具体响应(接收到)的事件。
当ApplicationContext被初始化或刷新时,会触发ContextRefreshedEvent事件,下面我们就实现一个ApplicationListener来监听此事件的发生,代码如下。
@Component // 需对该类进行Bean的实例化 public class LearnListener implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { // 打印容器中出事Bean的数量 System.out.println("监听器获得容器中初始化Bean数量:" + event.getApplication- Context().getBeanDefinitionCount()); } }
上面的LearnListener实现了ApplicationListener并监听ContextRefreshedEvent事件,当容器创建或刷新时,该监听器的onApplicationEvent方法会被调用,并打印出当前容器中Bean的数量。
在具体的实战业务中,我们也可以自定义事件,在完成业务之后手动触发对应的事件监听器,也就是手动调用ApplicationContext的publishEvent(ApplicationEvent event)方法。