【六】springboot启动源码 - registerListeners

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的构造方法中
【六】springboot启动源码 - registerListeners_第1张图片
getSpringFactoriesInstances方法
依然是通过SpringFactoriesLoader.loadFactoryNames(Class factoryType, ClassLoader classLoader),查找spring.factories下key为interface org.springframework.context.ApplicationListener的类名。
获取到类名后,通过构造器对这些类进行实例化
【六】springboot启动源码 - registerListeners_第2张图片
返回实例集合后,再将这些对象放入SpringApplication中
【六】springboot启动源码 - registerListeners_第3张图片

【六】springboot启动源码 - registerListeners_第4张图片
当SpringApplication开始调用run方法,在创建context之后的prepareContext方法中,会将SpringApplication的listeners设置到contextapplicationListeners中
【六】springboot启动源码 - registerListeners_第5张图片
prepareContext方法
【六】springboot启动源码 - registerListeners_第6张图片

contextLoaded方法
【六】springboot启动源码 - registerListeners_第7张图片

补充说明,可以看到这里有很多类似的方法,他们都是根据SpringApplicationRunListener的回调时机来触发
【六】springboot启动源码 - registerListeners_第8张图片

doWithListeners方法
【六】springboot启动源码 - registerListeners_第9张图片
补充说明一下,这里的listeners是基于spring SPI查询到的key为org.springframework.boot.SpringApplicationRunListener的实现类

【六】springboot启动源码 - registerListeners_第10张图片
【六】springboot启动源码 - registerListeners_第11张图片
遍历SpringApplicationRunListener,并通过Consumer执行listener.contextLoaded(context)【六】springboot启动源码 - registerListeners_第12张图片
调用EventPublishingRunListener重写方法contextLoaded,并将SpringApplication的listeners设置到context的applicationListeners中

【六】springboot启动源码 - registerListeners_第13张图片

进入正题registerListeners

  1. 将context的applicationListeners,注册到事件控制器(context的ApplicationEventMulticaster applicationEventMulticaster,默认实现类是SimpleApplicationEventMulticaster)的内部类(DefaultListenerRetriever)的Set> applicationListeners

Register statically specified listeners first.

通过spring spi 加载org.springframework.context.ApplicationListener
【六】springboot启动源码 - registerListeners_第14张图片
【六】springboot启动源码 - registerListeners_第15张图片

  1. 通过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
【六】springboot启动源码 - registerListeners_第16张图片
【六】springboot启动源码 - registerListeners_第17张图片
3. 加载earlyApplicationEvents到事件控制器,暂时不分析

Publish early application events now that we finally have a multicaster…

【六】springboot启动源码 - registerListeners_第18张图片

总结

  1. 通过spring spi 加载ApplicationListener的类,实例化后注入到context的applicationEventMulticaster中,DefaultListenerRetriever的applicationListeners集合
  2. 通过spring spi 加载EnableAutoConfiguration的类,将beanName注入到context的applicationEventMulticaster中,DefaultListenerRetriever的applicationListenerBeans集合

你可能感兴趣的:(springboot源码解析,HomeHomi脚手架,spring,boot,java,spring)