生命周期和事件監聽
一個應用的啟動過程和關閉過程是歸屬到“生命周期”這個概念的范疇。
典型的設計是在啟動和關閉過程中會觸發一系列的“事件”,我們只要監聽這些事件,就能參與到這個過程中來。
要想監聽事件,首先得有事件監聽器,就是常說的Listener。下面就是Spring提供的監聽器,如下圖01:
按規定所有的監聽器都要繼承Java提供的EventListener接口,這個接口是一個空的marker接口,其實就是標識一下。
事件一般都有多個,一般也有兩種常用解決方法:
要么定義多個監聽器接口,一個事件一個接口。
要么一個接口里定義多個方法,一個事件一個方法。
可惜的是,這兩種方法Spring都沒有采用,仍然只用了一個接口一個方法,那它是如何實現的呢?
相信大家已經看到,監聽器接口有一個泛型參數,沒錯,就是根據泛型參數的不同來區分不同事件的。
這個泛型參數就是事件對象,按規定所有的事件對象都要繼承Java提供的EventObject類,如下圖02:
Java提供這個類除了有標識作用外,還和事件源有關。任何事件都會有一個觸發者,它就是事件源。可以認為是事件的起源或來源。
既然所有事件都有,干脆提升到頂級父類里算了。如下圖03:
不同的事件,含義完全不同,所以差別很大,因此,通常一種事件會有屬於自己的一種事件對象。
我們只需要看下事件對象有多少種,就能知道事件有多少種。這種判斷方式一般都沒有問題。
下面就是和SpringBoot啟動有關的所有事件對象類型,如下圖04:
一共有七種事件對象,除去一種是處理失敗用的,還剩六種。也就是說我們可以通過六個事件參與到SpringBoot應用的啟動中去。
實現事件監聽器接口
監聽器就是接口,我們首先要實現這些接口,加入處理邏輯。然后把它們添加到應用中去就行了。
有六種事件對象,我們需要定義六個實現類。
事件對象為ApplicationStartingEvent,如下圖05:
事件對象為ApplicationEnvironmentPreparedEvent,如下圖06:
事件對象為ApplicationContextInitializedEvent,如下圖07:
事件對象為ApplicationPreparedEvent,如下圖08:
事件對象為ApplicationStartedEvent,如下圖09:
事件對象為ApplicationReadyEvent,如下圖10:
把這個六個實現類添加到SpringBoot應用中,如下圖11:
實現Runner接口
SpringBoot提供了兩個Runner接口,如下圖1213:
這兩個接口主要用於滿足那種應用剛啟動好后就需要立馬被執行的需求。如定時任務。
我們也來實現下這兩個接口,如下圖1415:
有一點需要注意的是,這兩個接口的實現類需要作為bean注冊到容器中去。
實現Spring容器初始化接口
如果我們需要對Spring容器進行一些自定義的初始化,可以實現這個接口,如下圖16:
這個接口的泛型參數其實就是容器對象。
我們也來實現下這個接口,如下圖1718:
我們可以多次實現這個接口,需要排序的話可以使用@Order注解或實現Ordered接口。
然后把這些實現類添加到SpringBoot應用中去,如下圖19:
啟動應用,觀察事件觸發的次序
啟動后首先觸發啟動事件,如下圖20:
接着要做的就是確認環境,創建Environment,然后觸發事件,表明環境已經OK了。如下圖21:
然后根據環境創建Spring容器對象,創建好后執行自定義容器初始化,如下圖22:
初始化完成后,觸發事件,表明容器就已經准備好了,如下圖23:
容器OK之后,就會加載資源(主要是注冊bean定義),加載完成后,就會觸發事件,如下圖24:
接着Spring容器就會進行refresh,refresh完成之后,其實Spring容器就已經成功啟動好了。
這時會觸發事件,如下圖25:
容器啟動好后,立馬就會執行Runner,如下圖26:
Runner執行完后,SpringBoot應用就真正啟動好了,進入了正常運行狀態。
這時會觸發最后一個事件,如下圖27:
我們可以根據需要,在對應的事件里完成自己的需求。
(END)
>>> 玩轉SpringBoot系列文章 <<<
【玩轉SpringBoot】用好條件相關注解,開啟自動配置之門
【玩轉SpringBoot】看似復雜的Environment其實很簡單
【玩轉SpringBoot】讓錯誤處理重新由web服務器接管
【玩轉SpringBoot】SpringBoot應用的啟動過程一覽表
>>> 品Spring系列文章 <<<
品Spring:SpringBoot和Spring到底有沒有本質的不同?
品Spring:SpringBoot輕松取勝bean定義注冊的“第一階段”
品Spring:SpringBoot發起bean定義注冊的“二次攻堅戰”
品Spring:注解之王@Configuration和它的一眾“小弟們”
品Spring:對@PostConstruct和@PreDestroy注解的處理方法
品Spring:對@Autowired和@Value注解的處理方法
品Spring:真沒想到,三十步才能完成一個bean實例的創建
品Spring:關於@Scheduled定時任務的思考與探索,結果尷尬了
>>> 熱門文章集錦 <<<
爸爸又給Spring MVC生了個弟弟叫Spring WebFlux
【面試】吃透了這些Redis知識點,面試官一定覺得你很NB(干貨 | 建議珍藏)
【面試】如果你這樣回答“什么是線程安全”,面試官都會對你刮目相看(建議珍藏)
【面試】迄今為止把同步/異步/阻塞/非阻塞/BIO/NIO/AIO講的這么清楚的好文章(快快珍藏)
【面試】一篇文章幫你徹底搞清楚“I/O多路復用”和“異步I/O”的前世今生(深度好文,建議珍藏)
作者是工作超過10年的碼農,現在任架構師。喜歡研究技術,崇尚簡單快樂。追求以通俗易懂的語言解說技術,希望所有的讀者都能看懂並記住。下面是公眾號的二維碼,歡迎關注!