SpringApplicationRunListener是SpringBoot应用启动过程中的核心事件监听器接口,它定义了应用启动过程中各个关键生命周期阶段的回调方法。其主要功能包括:
public interface SpringApplicationRunListener {
/**
* 应用启动时立即调用
*/
default void starting(ConfigurableBootstrapContext bootstrapContext) {
starting();
}
/**
* 环境准备完成后调用
*/
default void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,
ConfigurableEnvironment environment) {
environmentPrepared(environment);
}
/**
* 应用上下文创建后,资源加载前调用
*/
default void contextPrepared(ConfigurableApplicationContext context) {
}
/**
* 应用上下文加载完成,刷新前调用
*/
default void contextLoaded(ConfigurableApplicationContext context) {
}
/**
* 应用上下文刷新完成,命令执行前调用
*/
default void started(ConfigurableApplicationContext context) {
}
/**
* 应用完全就绪后调用
*/
default void running(ConfigurableApplicationContext context) {
}
/**
* 启动失败时调用
*/
default void failed(ConfigurableApplicationContext context, Throwable exception) {
}
}
监听器的加载始于SpringApplication的构造方法:
public SpringApplication(ResourceLoader resourceLoader, Class>... primarySources) {
// ...
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// ...
}
SpringFactoriesLoader负责从META-INF/spring.factories加载实现类:
private Collection getSpringFactoriesInstances(Class type) {
return getSpringFactoriesInstances(type, new Class>[] {});
}
private Collection getSpringFactoriesInstances(Class type,
Class>[] parameterTypes, Object... args) {
ClassLoader classLoader = getClassLoader();
Set names = new LinkedHashSet<>(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
private List createSpringFactoriesInstances(Class type,
Class>[] parameterTypes, ClassLoader classLoader,
Object[] args, Set names) {
List instances = new ArrayList<>(names.size());
for (String name : names) {
try {
Class> instanceClass = ClassUtils.forName(name, classLoader);
Assert.isAssignable(type, instanceClass);
Constructor> constructor = instanceClass.getConstructor(parameterTypes);
T instance = (T) BeanUtils.instantiateClass(constructor, args);
instances.add(instance);
} catch (Throwable ex) {
throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
}
}
return instances;
}
SpringApplicationRunListeners类封装了多个监听器的批量操作:
class SpringApplicationRunListeners {
private final Log log;
private final List listeners;
private final ApplicationStartup applicationStartup;
SpringApplicationRunListeners(Log log, Collection extends SpringApplicationRunListener> listeners,
ApplicationStartup applicationStartup) {
this.log = log;
this.listeners = new ArrayList<>(listeners);
this.applicationStartup = applicationStartup;
}
// 各生命周期方法的批量调用...
}
Mermaid
应用启动时的第一个回调,在SpringApplication.run()方法中:
public ConfigurableApplicationContext run(String... args) {
// ...
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
// ...
}
EventPublishingRunListener的实现:
@Override
public void starting(ConfigurableBootstrapContext bootstrapContext) {
this.initialMulticaster.multicastEvent(
new ApplicationStartingEvent(this.application, this.args));
}
环境准备完成后,上下文创建前:
private ConfigurableEnvironment prepareEnvironment(
SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
// ...
listeners.environmentPrepared(bootstrapContext, environment);
// ...
}
@Override
public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,
ConfigurableEnvironment environment) {
this.initialMulticaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(
this.application, this.args, environment));
}
上下文创建后,资源加载前:
private void prepareContext(ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
// ...
listeners.contextPrepared(context);
// ...
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
this.initialMulticaster.multicastEvent(new ApplicationContextInitializedEvent(
this.application, this.args, context));
}
4.
4 contextLoaded阶段
上下文加载完成,刷新前:
private void prepareContext(ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
// ...
listeners.contextLoaded(context);
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
// 无默认事件发布
}
上下文刷新完成,命令执行前:
private void callRunners(ApplicationContext context, ApplicationArguments args) {
// ...
listeners.started(context);
// ...
}
@Override
public void started(ConfigurableApplicationContext context) {
context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));
}
应用完全就绪后:
private void callRunners(ApplicationContext context, ApplicationArguments args) {
// ...
listeners.running(context);
// ...
}
@Override
public void running(ConfigurableApplicationContext context) {
context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context));
}
启动过程中任何阶段发生异常时:
private void handleRunFailure(ConfigurableApplicationContext context, Throwable exception,
SpringApplicationRunListeners listeners) {
// ...
listeners.failed(context, exception);
// ...
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
ApplicationFailedEvent event = new ApplicationFailedEvent(this.application,
this.args, context, exception);
if (context != null && context.isActive()) {
context.publishEvent(event);
}
else {
this.initialMulticaster.multicastEvent(event);
}
}
将SpringApplicationRunListener生命周期方法转换为标准Spring事件:
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
private final SpringApplication application;
private final String[] args;
private final SimpleApplicationEventMulticaster initialMulticaster;
@Override
public void starting(ConfigurableBootstrapContext bootstrapContext) {
this.initialMulticaster.multicastEvent(
new ApplicationStartingEvent(this.application, this.args));
}
// 其他方法实现...
}
生命周期方法 |
对应事件类型 |
starting |
ApplicationStartingEvent |
environmentPrepared |
ApplicationEnvironmentPreparedEvent |
contextPrepared |
ApplicationContextInitializedEvent |
started |
ApplicationStartedEvent |
running |
ApplicationReadyEvent |
failed |
ApplicationFailedEvent |
在后台线程中预初始化常用组件:
public class BackgroundPreinitializer implements ApplicationListener {
@Override
public void onApplicationEvent(SpringApplicationEvent event) {
if (event instanceof ApplicationStartingEvent) {
performPreinitialization();
}
}
private void performPreinitialization() {
try {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
runSafely(new ConversionServiceInitializer());
runSafely(new ValidationInitializer());
runSafely(new MessageConverterInitializer());
runSafely(new MBeanFactoryInitializer());
}
}, "background-preinit");
thread.start();
} catch (Exception ex) {
// 处理异常...
}
}
}
SpringBoot事件传播分为两个层次:
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
private final SimpleApplicationEventMulticaster initialMulticaster;
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);
}
}
// 事件广播方法...
}
@Override
public void started(ConfigurableApplicationContext context) {
// 通过ApplicationContext发布事件
context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));
}
public class CustomRunListener implements SpringApplicationRunListener {
private final Log logger = LogFactory.getLog(getClass());
public CustomRunListener(SpringApplication application, String[] args) {
// 构造器必须包含这两个参数
}
@Override
public void starting(ConfigurableBootstrapContext bootstrapContext) {
logger.info("应用启动开始");
}
@Override
public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,
ConfigurableEnvironment environment) {
logger.info("环境准备完成: " + environment);
}
@Override
public void running(ConfigurableApplicationContext context) {
logger.info("应用启动完成,服务已就绪");
}
}
在META-INF/spring.factories中配置:
Propertiesorg.springframework.boot.SpringApplicationRunListener=\
com.example.CustomRunListener
通过本文的深度解析,我们全面掌握了SpringApplicationRunListener在SpringBoot启动过程中的核心机制与实现原理。从加载机制、事件广播到各生命周期阶段的详细分析,这一扩展点为开发者提供了对应用启动过程的精细控制能力。合理运用这一机制,可以构建更加健壮、可观测的SpringBoot应用系统。