一、Spring Boot启动流程
在了解Spring Boot的启动顺序之前,我们需要先了解Spring Boot的启动流程。在Spring Boot启动时,会以SpringApplication为入口进行启动。SpringApplication会开启一些基本的事件(ApplicationEvent),并将这些事件发送给所有注册了相应监听器(ApplicationListener)的组件进行处理。
因此,Spring Boot的启动流程可以概括为以下几步:
- 创建SpringApplication
- 执行SpringApplication的run()方法
- SpringApplication会依次发布以下事件:ApplicationStartingEvent、ApplicationEnvironmentPreparedEvent、ApplicationContextInitializedEvent、ApplicationPreparedEvent、ApplicationStartedEvent、ApplicationReadyEvent、ApplicationFailedEvent
- 所有注册了相应的监听器会处理它们感兴趣的事件
二、Spring Boot启动顺序
1. SpringApplication构造函数
在创建SpringApplication实例的时候,Spring Boot会进行相关的初始化和准备阶段。在这个过程中,Spring Boot会根据一些默认设置来决定要使用哪些特性,并对这些特性进行配置。比如,自动配置、Profile、配置文件等。
示例代码
@SpringBootApplication
public class SpringApplicationDemo {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(SpringApplicationDemo.class);
application.run(args);
}
}
2. ApplicationStartingEvent
在调用SpringApplication的run()方法之前,SpringApplication会发布ApplicationStartingEvent事件。这个事件表示SpringApplication即将启动。在这个事件中,我们可以进行一些相关的操作,比如输出程序启动日志。
示例代码
@Component
public class StartingEventListener implements ApplicationListener<ApplicationStartingEvent> {
private static final Logger LOGGER = LoggerFactory.getLogger(StartingEventListener.class);
@Override
public void onApplicationEvent(ApplicationStartingEvent event) {
LOGGER.info("Application is starting with args: {}",
Arrays.toString(event.getArgs()));
}
}
3. ApplicationEnvironmentPreparedEvent
在执行run()方法之前,SpringApplication会发布ApplicationEnvironmentPreparedEvent事件。在这个事件中,我们可以对应用程序的环境进行一些自定义配置,比如添加自定义属性、配置环境变量等。
示例代码
@Component
public class EnvironmentPreparedEventListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
Map<String, Object> properties = new HashMap();
properties.put("server.port", 8081);
PropertiesPropertySource propertySource = new PropertiesPropertySource("customProperties", properties);
environment.getPropertySources().addFirst(propertySource);
}
}
4. ApplicationContextInitializedEvent
在执行run()方法时,Spring Boot会发布ApplicationContextInitializedEvent事件。这个事件表示ApplicationContext正在被创建,但是还没有加载任何Bean。在这个事件中,我们可以手动往ApplicationContext中添加一些Bean。
示例代码
@Component
public class ContextInitializedEventListener implements ApplicationListener<ApplicationContextInitializedEvent> {
@Override
public void onApplicationEvent(ApplicationContextInitializedEvent event) {
ConfigurableApplicationContext context = event.getApplicationContext();
context.getBeanFactory().registerSingleton("myBean", new Object());
}
}
5. ApplicationPreparedEvent
在上一步中,ApplicationContext成功创建并加载了所有的Bean。在执行run()方法之前,Spring Boot会发布ApplicationPreparedEvent事件。在这个事件中,我们可以获取ApplicationContext,并进行一些自定义配置。
示例代码
@Component
public class PreparedEventListener implements ApplicationListener<ApplicationPreparedEvent> {
@Override
public void onApplicationEvent(ApplicationPreparedEvent event) {
ConfigurableApplicationContext context = event.getApplicationContext();
DataSource dataSource = context.getBean(DataSource.class);
try {
dataSource.getConnection().close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
6. ApplicationStartedEvent
在上一步结束后,ApplicationContext会被刷新,并启动完成。在这个时候,Spring Boot会发布ApplicationStartedEvent事件。在这个事件中,我们可以进行一些启动后的操作,比如数据初始化。
示例代码
@Component
public class StartedEventListener implements ApplicationListener<ApplicationStartedEvent> {
private static final Logger LOGGER = LoggerFactory.getLogger(StartedEventListener.class);
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
LOGGER.info("Application has started...");
}
}
7. ApplicationReadyEvent
当应用程序启动并且ApplicationContext中的Bean都已经装配好之后,Spring Boot会发布ApplicationReadyEvent事件,这个事件表示此时应用程序已经准备好了。我们可以在这种情况下进行一些定时任务的启动、消息的处理等操作。
示例代码
@Component
public class ReadyEventListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("I'm a TimerTask!");
}
};
Timer timer = new Timer();
timer.schedule(task, 5000L);
}
}
8. ApplicationFailedEvent
如果应用程序启动失败,Spring Boot会发布ApplicationFailedEvent事件,这个事件表示应用程序启动过程中出现了错误。在这个事件中我们可以获取到失败的原因,并进行相应的处理。
示例代码
@Component
public class FailedEventListener implements ApplicationListener<ApplicationFailedEvent> {
@Override
public void onApplicationEvent(ApplicationFailedEvent event) {
Throwable throwable = event.getException();
LOGGER.error("Application failed to start: {}", throwable.getMessage());
}
}
三、总结
通过本文的介绍,我们可以详细了解Spring Boot启动顺序背后的机制和原理。在实际开发中,我们可以根据自己的需求选择合适的时间点进行自定义操作,从而达到更加优美的应用启动顺序。
原创文章,作者:DMJXT,如若转载,请注明出处:https://www.506064.com/n/370404.html
微信扫一扫
支付宝扫一扫