一、示例
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);
}