spring boot · 2025-01-31 0

SpringBoot 事件触发时机

一、示例

1.pom

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.2</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

2.java

@SpringBootApplication
public class WebBoot {

    public static void main(String[] args) {
        SpringApplication.run(WebBoot.class, args);
    }
}
public class MyStartingEvent implements ApplicationListener<ApplicationStartingEvent> {

    @Override
    public void onApplicationEvent(ApplicationStartingEvent event) {
        System.out.println("- - - MyStartingEvent - - -");
    }
}

public class MyEnvironmentPreparedEvent implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {

    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
        System.out.println("- - - MyEnvironmentPreparedEvent - - -");
    }
}

public class MyContextInitializedEvent implements ApplicationListener<ApplicationContextInitializedEvent> {

    @Override
    public void onApplicationEvent(ApplicationContextInitializedEvent event) {
        System.out.println("- - - MyContextInitializedEvent - - -");
    }
}

public class MyPreparedEvent implements ApplicationListener<ApplicationPreparedEvent> {

    @Override
    public void onApplicationEvent(ApplicationPreparedEvent event) {
        System.out.println("- - - MyPreparedEvent - - -");
    }
}

public class MyStartedEvent implements ApplicationListener<ApplicationStartedEvent> {

    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        System.out.println("- - - MyStartedEvent - - -");
    }
}

public class MyReadyEvent implements ApplicationListener<ApplicationReadyEvent> {

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        System.out.println("- - - MyReadyEvent - - -");
    }
}

3.spring.factories

META-INF/spring.factories

org.springframework.context.ApplicationListener=\
org.example.starter.MyStartingEvent,\
org.example.starter.MyEnvironmentPreparedEvent,\
org.example.starter.MyContextInitializedEvent,\
org.example.starter.MyPreparedEvent,\
org.example.starter.MyStartedEvent,\
org.example.starter.MyReadyEvent

4.结果

结果如下:

- - - MyStartingEvent - - -
- - - MyEnvironmentPreparedEvent - - -

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.7.2)

- - - MyContextInitializedEvent - - -
2025-02-19 23:09:02.553  INFO 5378 --- [           main] org.example.WebBoot                      : Starting WebBoot using Java 1.8.0_432 on zxm-pc with PID 5378 (/home/zxm/IdeaProjects/jdk8-demo/spring-boot/spring-boot-web-demo/target/classes started by zxm in /home/zxm/IdeaProjects/jdk8-demo)
2025-02-19 23:09:02.555  INFO 5378 --- [           main] org.example.WebBoot                      : No active profile set, falling back to 1 default profile: "default"
- - - MyPreparedEvent - - -
2025-02-19 23:09:03.050  INFO 5378 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 18080 (http)
2025-02-19 23:09:03.054  INFO 5378 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2025-02-19 23:09:03.054  INFO 5378 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.65]
2025-02-19 23:09:03.090  INFO 5378 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2025-02-19 23:09:03.090  INFO 5378 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 503 ms
2025-02-19 23:09:03.244  INFO 5378 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 18080 (http) with context path ''
2025-02-19 23:09:03.249  INFO 5378 --- [           main] org.example.WebBoot                      : Started WebBoot in 0.947 seconds (JVM running for 1.226)
- - - MyStartedEvent - - -
- - - MyReadyEvent - - -

二、事件触发时机

调用事件顺序

1) initialMulticaster.multicastEvent 触发 ApplicationStartingEvent 事件,默认有 8 个 listener
2) initialMulticaster.multicastEvent 触发 ApplicationEnvironmentPreparedEvent 事件,默认有 8 个 listener
3) initialMulticaster.multicastEvent 触发 ApplicationContextInitializedEvent 事件,默认有 8 个 listener
4) events.multicastEvent 触发 BootstrapContextClosedEvent 事件,默认无 listener
5)initialMulticaster.multicastEvent 触发 ApplicationPreparedEvent 事件,默认有 8 个 listener
6) applicationContext.publishEvent 触发 ServletWebServerInitializedEvent 事件
7) applicationContext.publishEvent 触发 ContextRefreshedEvent 事件
8) applicationContext.publishEvent 触发 ApplicationStartedEvent 事件
9) 执行 runners
10) applicationContext.publishEvent 触发 ApplicationReadyEvent

总结,对于自定义的 ApplicationStartingEvent、ApplicationEnvironmentPreparedEvent、ApplicationContextInitializedEvent 需要定义到 spring.factories 文件才能被执行
对于自定义的 ContextRefreshedEvent、ApplicationReadyEvent 可以定义会 spring.factories 文件 或者定义为 bean

initialMulticaster 执行的,即 spring.factories 定义的有:

0 = {EnvironmentPostProcessorApplicationListener@1999} 
1 = {AnsiOutputApplicationListener@2000} 
2 = {LoggingApplicationListener@2001} 
3 = {BackgroundPreinitializer@2002} 
4 = {DelegatingApplicationListener@2003} 
5 = {ParentContextCloserApplicationListener@2004} 
6 = {ClearCachesApplicationListener@2005} 
7 = {FileEncodingApplicationListener@2006} 

applicationContext 包含 Listener

0 = {RSocketPortInfoApplicationContextInitializer$Listener@4651} 
1 = {ServerPortInfoApplicationContextInitializer@4652} 
2 = {ConditionEvaluationReportLoggingListener$ConditionEvaluationReportListener@4653} 
3 = {EnvironmentPostProcessorApplicationListener@1999} 
4 = {AnsiOutputApplicationListener@2000} 
5 = {LoggingApplicationListener@2001} 
6 = {BackgroundPreinitializer@2002} 
7 = {DelegatingApplicationListener@2003} 
8 = {ParentContextCloserApplicationListener@2004} 
9 = {ClearCachesApplicationListener@2005} 
10 = {FileEncodingApplicationListener@2006} 
11 = {SpringApplicationShutdownHook$ApplicationContextClosedListener@4654} 

1.从 spring.factories 文件读取定义的 ApplicationListener,注册 8 个 Listener

// SpringApplication.java
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
    return run(new Class<?>[] { primarySource }, args);
}

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
    return new SpringApplication(primarySources).run(args);
}

public SpringApplication(Class<?>... primarySources) {
    this(null, primarySources);
}

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    this.bootstrapRegistryInitializers = new ArrayList<>(
            getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
    setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = deduceMainApplicationClass();
}

2.EventPublishingRunListener

从 spring.factories 文件读取定义的 SpringApplicationRunListener,为 EventPublishingRunListener
把一组 ApplicationListener,放入 EventPublishingRunListener

// EventPublishingRunListener.java
public ConfigurableApplicationContext run(String... args) {
    ...
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args);
}

private SpringApplicationRunListeners getRunListeners(String[] args) {
    Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
    return new SpringApplicationRunListeners(logger,
            getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args),
            this.applicationStartup);
}
// EventPublishingRunListener.java
public EventPublishingRunListener(SpringApplication application, String[] args) {
    this.application = application;
    this.args = args;
    this.initialMulticaster = new SimpleApplicationEventMulticaster();
    for (ApplicationListener<?> listener : application.getListeners()) {
        this.initialMulticaster.addApplicationListener(listener);
    }
}
// SimpleApplicationEventMulticaster.java
private final DefaultListenerRetriever defaultRetriever = new DefaultListenerRetriever();

@Override
public void addApplicationListener(ApplicationListener<?> listener) {
    synchronized (this.defaultRetriever) {
        // Explicitly remove target for a proxy, if registered already,
        // in order to avoid double invocations of the same listener.
        Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
        if (singletonTarget instanceof ApplicationListener) {
            this.defaultRetriever.applicationListeners.remove(singletonTarget);
        }
        this.defaultRetriever.applicationListeners.add(listener);
        this.retrieverCache.clear();
    }
}

3.触发 ApplicationStartingEvent 事件

(此时的 listener 是 spring.factories 文件定义的,默认有 8 个 listener)

initialMulticaster.multicastEvent 触发 ApplicationStartingEvent 事件

// SpringApplication.java
public ConfigurableApplicationContext run(String... args) {
    ...
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);
}
// EventPublishingRunListener.java
@Override
public void starting(ConfigurableBootstrapContext bootstrapContext) {
    this.initialMulticaster
            .multicastEvent(new ApplicationStartingEvent(bootstrapContext, this.application, this.args));
}
// SimpleApplicationEventMulticaster.java

@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    Executor executor = getTaskExecutor();
    for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        if (executor != null) {
            executor.execute(() -> invokeListener(listener, event));
        }
        else {
            invokeListener(listener, event);
        }
    }
}

protected Collection<ApplicationListener<?>> getApplicationListeners(
        ApplicationEvent event, ResolvableType eventType) {
    ...
    return retrieveApplicationListeners(eventType, sourceType, newRetriever);       
}

private Collection<ApplicationListener<?>> retrieveApplicationListeners(
        ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable CachedListenerRetriever retriever) {
    ...
    Set<ApplicationListener<?>> listeners;
    Set<String> listenerBeans;
    synchronized (this.defaultRetriever) {
        listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
        listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
    }   

    for (ApplicationListener<?> listener : listeners) {
        if (supportsEvent(listener, eventType, sourceType)) {
            if (retriever != null) {
                filteredListeners.add(listener);
            }
            allListeners.add(listener);
        }
    }
    ...
}
// EventPublishingRunListener.java
@Override
public void starting(ConfigurableBootstrapContext bootstrapContext) {
    this.initialMulticaster
            .multicastEvent(new ApplicationStartingEvent(bootstrapContext, this.application, this.args));
}

4.触发 ApplicationEnvironmentPreparedEvent 事件

(此时的 listener 是 spring.factories 文件定义的,默认有 8 个 listener)

initialMulticaster.multicastEvent 触发 ApplicationEnvironmentPreparedEvent 事件

// SpringApplication.java
public ConfigurableApplicationContext run(String... args) {
    ...
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        ...
    }
}

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
        DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
    ...
    listeners.environmentPrepared(bootstrapContext, environment);   
    ...
    return environment;
}
// EventPublishingRunListener.java
@Override
public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,
        ConfigurableEnvironment environment) {
    this.initialMulticaster.multicastEvent(
            new ApplicationEnvironmentPreparedEvent(bootstrapContext, this.application, this.args, environment));
}

5.ApplicationContextInitializedEvent 事件
(此时的 listener 是 spring.factories 文件定义的,默认有 8 个 listener)

initialMulticaster.multicastEvent 触发 ApplicationContextInitializedEvent 事件

// SpringApplication.java
public ConfigurableApplicationContext run(String... args) {
    ...
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        ...
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
    }
}

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
        DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
    ...
    listeners.environmentPrepared(bootstrapContext, environment);   
    ...
    return environment;
}

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
            ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments, Banner printedBanner) {
    ...
    listeners.contextPrepared(context);
    ...
}

6.注册 listener 到 applicationContext

有些 Initializers 会注册 listener 到 applicationContext

0 = {RSocketPortInfoApplicationContextInitializer$Listener@4284}
1 = {ServerPortInfoApplicationContextInitializer@4308}
2 = {ConditionEvaluationReportLoggingListener$ConditionEvaluationReportListener@4313}

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
        ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
        ApplicationArguments applicationArguments, Banner printedBanner) {
    ...
    applyInitializers(context);     
    ...
}

protected void applyInitializers(ConfigurableApplicationContext context) {
    for (ApplicationContextInitializer initializer : getInitializers()) {
        Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
                ApplicationContextInitializer.class);
        Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
        initializer.initialize(context);
    }
}
// RSocketPortInfoApplicationContextInitializer.java
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
    applicationContext.addApplicationListener(new Listener(applicationContext));
}
// ServerPortInfoApplicationContextInitializer.java
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
    applicationContext.addApplicationListener(this);
}
// ConditionEvaluationReportLoggingListener.java
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
    ...
    applicationContext.addApplicationListener(new ConditionEvaluationReportListener());
    ...
}

7.BootstrapContextClosedEvent 事件
(此时的 listener,默认无 listener)

events.multicastEvent 触发 BootstrapContextClosedEvent 事件

// SpringApplication.java
public ConfigurableApplicationContext run(String... args) {
    ...
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        ...
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
    }
}

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
        DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
    ...
    listeners.environmentPrepared(bootstrapContext, environment);   
    ...
    return environment;
}

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
            ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments, Banner printedBanner) {
    ...
    listeners.contextPrepared(context);
    bootstrapContext.close(context);
    ...
}
// DefaultBootstrapContext.java
public void close(ConfigurableApplicationContext applicationContext) {
    this.events.multicastEvent(new BootstrapContextClosedEvent(this, applicationContext));
}

8.注册 listener 到 applicationContext

并把 8 个 listner 放入 ApplicationContext,此时 ApplicationContext 有 11 个 listener

// SpringApplication.java
public ConfigurableApplicationContext run(String... args) {
    ...
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        ...
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
    }
}

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
            ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments, Banner printedBanner) {
    ...
    listeners.contextPrepared(context);
    bootstrapContext.close(context);
    ...
    listeners.contextLoaded(context);
}
// EventPublishingRunListener.java
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
    for (ApplicationListener<?> listener : this.application.getListeners()) {
        if (listener instanceof ApplicationContextAware) {
            ((ApplicationContextAware) listener).setApplicationContext(context);
        }
        context.addApplicationListener(listener);
    }
    this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
}

9.ApplicationPreparedEvent 事件

(此时的 listener 是 spring.factories 文件定义的,默认有 8 个 listener)

initialMulticaster.multicastEvent 触发 ApplicationPreparedEvent 事件

// SpringApplication.java
public ConfigurableApplicationContext run(String... args) {
    ...
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        ...
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
    }
}

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
        DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
    ...
    listeners.environmentPrepared(bootstrapContext, environment);   
    ...
    return environment;
}

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
            ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments, Banner printedBanner) {
    ...
    listeners.contextPrepared(context);
    bootstrapContext.close(context);
    ...
    listeners.contextLoaded(context);
}
// DefaultBootstrapContext.java
public void close(ConfigurableApplicationContext applicationContext) {
    this.events.multicastEvent(new BootstrapContextClosedEvent(this, applicationContext));
}
// EventPublishingRunListener.java
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
    for (ApplicationListener<?> listener : this.application.getListeners()) {
        if (listener instanceof ApplicationContextAware) {
            ((ApplicationContextAware) listener).setApplicationContext(context);
        }
        context.addApplicationListener(listener);
    }
    this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
}

10.注册 listener 到 applicationContext

// SpringApplication.java
public ConfigurableApplicationContext run(String... args) {
    ...
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        ...
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
        refreshContext(context);
        ...
    }
}

private void refreshContext(ConfigurableApplicationContext context) {
    if (this.registerShutdownHook) {
        shutdownHook.registerApplicationContext(context);
    }
    refresh(context);
}
// SpringApplicationShutdownHook.java
private final ApplicationContextClosedListener contextCloseListener = new ApplicationContextClosedListener();

void registerApplicationContext(ConfigurableApplicationContext context) {
    addRuntimeShutdownHookIfNecessary();
    synchronized (SpringApplicationShutdownHook.class) {
        assertNotInProgress();
        context.addApplicationListener(this.contextCloseListener);
        this.contexts.add(context);
    }
}

11.注册 listeners

执行 invokeBeanFactoryPostProcessors 会注册一些 listeners,例如会注册 SharedMetadataReaderFactoryContextInitializer$SharedMetadataReaderFactoryBean
执行 registerListeners,从 spring 容器中查询 ApplicationListener

// SpringApplication.java
public ConfigurableApplicationContext run(String... args) {
    ...
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        ...
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
        refreshContext(context);
    }
}

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
        DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
    ...
    listeners.environmentPrepared(bootstrapContext, environment);   
    ...
    return environment;
}

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
            ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments, Banner printedBanner) {
    ...
    listeners.contextPrepared(context);
    bootstrapContext.close(context);
    ...
    listeners.contextLoaded(context);
}

private void refreshContext(ConfigurableApplicationContext context) {
    if (this.registerShutdownHook) {
        shutdownHook.registerApplicationContext(context);
    }
    refresh(context);
}

protected void refresh(ConfigurableApplicationContext applicationContext) {
    applicationContext.refresh();
}
// DefaultBootstrapContext.java
public void close(ConfigurableApplicationContext applicationContext) {
    this.events.multicastEvent(new BootstrapContextClosedEvent(this, applicationContext));
}
// EventPublishingRunListener.java
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
    for (ApplicationListener<?> listener : this.application.getListeners()) {
        if (listener instanceof ApplicationContextAware) {
            ((ApplicationContextAware) listener).setApplicationContext(context);
        }
        context.addApplicationListener(listener);
    }
    this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
}
// AnnotationConfigServletWebServerApplicationContext.java
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);    

        try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);
            beanPostProcess.end();

            // Initialize message source for this context.
            initMessageSource();

            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            onRefresh();

            // Check for listener beans and register them.
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            finishRefresh();
        }
    ...
    }
}

protected void registerListeners() {
    // Register statically specified listeners first.
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let post-processors apply to them!
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }
    ...
}
// ApplicationListenerDetector.java
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
    if (bean instanceof ApplicationListener) {
        ...
        this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);    
        ...
    }
}

12.触发 ServletWebServerInitializedEvent 事件

applicationContext.publishEvent 触发 ServletWebServerInitializedEvent 事件

// AnnotationConfigServletWebServerApplicationContext.java
@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

        // Prepare this context for refreshing.
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);
            beanPostProcess.end();

            // Initialize message source for this context.
            initMessageSource();

            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            onRefresh();

            // Check for listener beans and register them.
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            finishRefresh();
        }
        ...
    }
}

protected void finishRefresh() { 
    ...
    getLifecycleProcessor().onRefresh();
    ...
}
// WebServerStartStopLifecycle.java
@Override
public void start() {
    this.webServer.start();
    this.running = true;
    this.applicationContext
            .publishEvent(new ServletWebServerInitializedEvent(this.webServer, this.applicationContext));
}

13.触发 ContextRefreshedEvent 事件

applicationContext.publishEvent 触发 ContextRefreshedEvent 事件

// AnnotationConfigServletWebServerApplicationContext.java
@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

        // Prepare this context for refreshing.
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);
            beanPostProcess.end();

            // Initialize message source for this context.
            initMessageSource();

            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            onRefresh();

            // Check for listener beans and register them.
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            finishRefresh();
        }
        ...
    }
}

protected void finishRefresh() {
    publishEvent(new ContextRefreshedEvent(this));
}

14.触发 ApplicationStartedEvent 事件

applicationContext.publishEvent 触发 ApplicationStartedEvent 事件

// SpringApplication.java
public ConfigurableApplicationContext run(String... args) {
    ...
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        ...
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
        refreshContext(context);
        ...
        listeners.started(context, timeTakenToStartup);
    }
}
// EventPublishingRunListener.java
@Override
public void started(ConfigurableApplicationContext context, Duration timeTaken) {
    context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context, timeTaken));
    AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
}

15.执行 Runners

// SpringApplication.java
public ConfigurableApplicationContext run(String... args) {
    ...
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        ...
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
        refreshContext(context);
        ...
        listeners.started(context, timeTakenToStartup);
        callRunners(context, applicationArguments);
    }
}

private void callRunners(ApplicationContext context, ApplicationArguments args) {
    List<Object> runners = new ArrayList<>();
    runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
    runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
    AnnotationAwareOrderComparator.sort(runners);
    for (Object runner : new LinkedHashSet<>(runners)) {
        if (runner instanceof ApplicationRunner) {
            callRunner((ApplicationRunner) runner, args);
        }
        if (runner instanceof CommandLineRunner) {
            callRunner((CommandLineRunner) runner, args);
        }
    }
}

16.触发 ApplicationReadyEvent 事件

applicationContext.publishEvent 触发 ApplicationReadyEvent

// SpringApplication.java
public ConfigurableApplicationContext run(String... args) {
    ...
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        ...
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
        refreshContext(context);
        ...
        listeners.started(context, timeTakenToStartup);
        callRunners(context, applicationArguments);
    }
    ...
    try {
        ...
        listeners.ready(context, timeTakenToReady);
    }
    ...
}
// EventPublishingRunListener.java
@Override
public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
    context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context, timeTaken));
    AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
}