1. /**
  2. * 添加实现了ApplicationListener的bean作为监听器
  3. * 这些监听器可以以一个不是bean对象的形式被添加而不会影响其它的监听器
  4. * Add beans that implement ApplicationListener as listeners.
  5. * Doesn't affect other listeners, which can be added without being beans.
  6. */
  7. protected void registerListeners() {
  8. // 首先注册静态的指定的监听器,注册的是特殊的事件监听器,而不是配置中的bean
  9. // 所谓静态指定的监听器,就是容器在初始化时已经指定的一些监听器,相当于默认的一些监听器。
  10. // getApplicationListeners就是获取applicationListeners
  11. for (ApplicationListener<?> listener : getApplicationListeners()) {
  12. getApplicationEventMulticaster().addApplicationListener(listener);
  13. }
  14. /**
  15. * 从容器中获取所有实现了ApplicationListener接口的bd的bdName
  16. * 放入applicationListenerBeans
  17. */
  18. String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
  19. for (String listenerBeanName : listenerBeanNames) {
  20. getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
  21. }
  22. /**
  23. * 这里先发布早期的监听器
  24. */
  25. Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
  26. this.earlyApplicationEvents = null;
  27. if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
  28. for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
  29. getApplicationEventMulticaster().multicastEvent(earlyEvent);
  30. }
  31. }
  32. }

二、通过addApplicationListener(listen)注册监听器

关于ApplicationEventMulticaster的详细介绍可以参考这篇文章:
06-Spring事件监听机制及原理

https://www.its404.com/article/yu_kang/88727188

三、自定义实现ApplicationListen接口的bd

接口编程式实现监听器

四、发布早期的监听器这里最后一步还会发布早期的事件,默认为空

05-Spring源码refresh-registerListeners() - 图1

最难的就是理解这个this.earlyApplicationListeners。如果我们调用两次refresh()方法,那么这里的this.earlyApplicationListeners就不为空了。

  1. public static void main(String[] args) {
  2. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
  3. // 注册监听器
  4. context.addApplicationListener(new DemoMyListener());
  5. // 注册配置类
  6. context.register(AppConfig.class);
  7. // 刷新上下文
  8. context.refresh();
  9. }