【Spring boot學習】事件啟動順序
ApplicationStartedEvent
事件,所以在2.0版本中所有的事件按執行的先後順序如下:
ApplicationStartingEvent
ApplicationEnvironmentPreparedEvent
ApplicationPreparedEvent
ApplicationStartedEvent
<= 新增的事件ApplicationReadyEvent
ApplicationFailedEvent
從上面的列表中,我們可以看到ApplicationStartedEvent
位於ApplicationPreparedEvent
之後,ApplicationReadyEvent
下面我們通過程式碼的方式來直觀的感受這個事件的切入位置,以便與將來我們在這個切入點加入自己需要的邏輯。
第一步:我們可以編寫ApplicationPreparedEvent
、ApplicationStartedEvent
以及ApplicationReadyEvent
三個事件的監聽器,然後在這三個事件觸發的時候列印一些日誌來觀察它們各自的切入點,比如:
@Slf4j public class ApplicationPreparedEventListener implements ApplicationListener<ApplicationPreparedEvent> { @Override public void onApplicationEvent(ApplicationPreparedEvent event) { log.info("......ApplicationPreparedEvent......"); } } @Slf4j public class ApplicationStartedEventListener implements ApplicationListener<ApplicationStartedEvent> { @Override public void onApplicationEvent(ApplicationStartedEvent event) { log.info("......ApplicationStartedEvent......"); } } @Slf4j public class ApplicationReadyEventListener implements ApplicationListener<ApplicationReadyEvent> { @Override public void onApplicationEvent(ApplicationReadyEvent event) { log.info("......ApplicationReadyEvent......"); } } |
第二步:在/src/main/resources/
目錄下新建:META-INF/spring.factories
配置檔案,通過配置org.springframework.context.ApplicationListener
來載入上面我們編寫的監聽器。
org.springframework.context.ApplicationListener= com.didispace.ApplicationPreparedEventListener,\ com.didispace.ApplicationReadyEventListener,\ com.didispace.ApplicationStartedEventListener |
此時,我們執行Spring Boot應用可以獲得類似如下日誌輸出:
下面可以看看官方文件對ApplicationStartedEvent
和ApplicationReadyEvent
的解釋:從日誌中我們可以看到清晰的看到ApplicationPreparedEvent
、ApplicationStartedEvent
以及ApplicationReadyEvent
三個事件的切入點。通過這個例子可能讀者會感到疑問:ApplicationStartedEvent
和ApplicationReadyEvent
從事件命名和日誌輸出位置來看,都是應用載入完成之後的事件,它們是否有什麼區別呢?
An ApplicationStartedEvent is sent after the context has been refreshed but before any application and command-line runners have been called.An ApplicationReadyEvent is sent after any application and command-line runners have been called. It indicates that the application is ready to service requests
從文件中我們可以知道他們兩中間還有一個過程就是command-line runners
被呼叫的內容。所以,為了更準確的感受這兩個事件的區別,我們在應用主類中加入CommandLineRunner
的實現,比如:
@Slf4j @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public DataLoader dataLoader() { return new DataLoader(); } @Slf4j static class DataLoader implements CommandLineRunner { @Override public void run(String... strings) throws Exception { log.info("Loading data..."); } } } |
最後,我們再執行程式,此時我們可以發現這兩個事件中間輸出了上面定義的DataLoader
的輸出內容,具體如下:
2018-03-07 18:15:20.845 INFO 83387 --- [main] c.d.ApplicationStartedEventListener : ......ApplicationStartedEvent...... 2018-03-07 18:15:20.846 INFO 83387 --- [main] com.didispace.Application$DataLoader : Loading data... 2018-03-07 18:15:20.847 INFO 83387 --- [main] c.d.ApplicationReadyEventListener : ......ApplicationReadyEvent......zhua |