registerListeners 源码解析
Check for listener beans and register them.
监听器注册
自定义监听事件
package org.hopehomi.core.tool.support.listener;
import org.springframework.context.ApplicationEvent;
/**
* @author Ledison
* @date 2023/3/22
*/
public class ForDebuggerEvent extends ApplicationEvent {
public ForDebuggerEvent(Object source) {
super(source);
}
public void executeEvent() {
System.out.println("ForDebuggerEvent executeEvent");
}
}
自定义事件监听器
package org.hopehomi.core.tool.support.listener;
import org.springframework.context.ApplicationListener;
/**
*
* @author Ledison
* @date 2023/3/22
*/
public class ForDebuggerEventListener implements ApplicationListener<ForDebuggerEvent> {
@Override
public void onApplicationEvent(ForDebuggerEvent event) {
event.executeEvent();
}
}
自定义事件生产类
package org.hopehomi.core.tool.support.listener;
import cn.hutool.extra.spring.SpringUtil;
import java.util.HashMap;
/**
* @author Ledison
* @date 2023/3/22
*/
public class ForDebuggerEventPusher {
public static void pushEvent() {
SpringUtil.publishEvent(new ForDebuggerEvent(new HashMap<>()));
}
}
ApplicationListener实现类什么时候被加载并实例化的
在SpringApplication的构造方法中
getSpringFactoriesInstances方法
依然是通过SpringFactoriesLoader.loadFactoryNames(Class<?> factoryType, ClassLoader classLoader),查找spring.factories下key为interface org.springframework.context.ApplicationListener的类名。
获取到类名后,通过构造器对这些类进行实例化
返回实例集合后,再将这些对象放入SpringApplication中
当SpringApplication开始调用run方法,在创建context之后的prepareContext方法中,会将SpringApplication的listeners设置到contextapplicationListeners中
prepareContext方法
contextLoaded方法
补充说明,可以看到这里有很多类似的方法,他们都是根据SpringApplicationRunListener的回调时机来触发
doWithListeners方法
补充说明一下,这里的listeners是基于spring SPI查询到的key为org.springframework.boot.SpringApplicationRunListener的实现类
遍历SpringApplicationRunListener,并通过Consumer执行listener.contextLoaded(context)
调用EventPublishingRunListener重写方法contextLoaded,并将SpringApplication的listeners设置到context的applicationListeners中
进入正题registerListeners
- 将context的applicationListeners,注册到事件控制器(context的ApplicationEventMulticaster applicationEventMulticaster,默认实现类是SimpleApplicationEventMulticaster)的内部类(DefaultListenerRetriever)的Set<ApplicationListener<?>> applicationListeners中
Register statically specified listeners first.
通过spring spi 加载org.springframework.context.ApplicationListener
- 通过beanFactory的beanDefinitionNames获取类型为ApplicationListener的bean名称集合,注册到事件控制器的applicationListenerBeans中
Do not initialize FactoryBeans here: We need to leave all regular beans
uninitialized to let post-processors apply to them!
通过spring spi 加载org.springframework.boot.autoconfigure.EnableAutoConfiguration
3. 加载earlyApplicationEvents到事件控制器,暂时不分析
Publish early application events now that we finally have a multicaster…
总结
- 通过spring spi 加载ApplicationListener的类,实例化后注入到context的applicationEventMulticaster中,DefaultListenerRetriever的applicationListeners集合
- 通过spring spi 加载EnableAutoConfiguration的类,将beanName注入到context的applicationEventMulticaster中,DefaultListenerRetriever的applicationListenerBeans集合