一、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/zh-tw/n/370404.html