SpringBoot日志源碼解析:日志監(jiān)聽器的注冊方法及觸發(fā)
SpringBoot日志源碼解析
Spring Boot 使用 Commons Logging 進(jìn)行所有內(nèi)部日志的記錄。SpringBoot 同時提供了Java Util Logging、Log4J2 和 Logback 的默認(rèn)配置 ,都可以通過預(yù)置的配置來設(shè)置控制臺和文件格式的日志輸出。本章重點介紹如何觸發(fā) Spring Boot 日志及相關(guān)初始化處理機(jī)制。

?LoggingApplicationListener的觸發(fā)
講到日志的觸發(fā)過程,我們首先看一下日志監(jiān)聽器
LoggingApplicationListener 的注冊方法,在 之 前章節(jié)中我們已經(jīng)講到 , 在 Spring Boot 啟 動 的 過 程 中 會 獲 得META-INF/spring .factories 配置文件中的 Aplication 注冊監(jiān)聽器,其中就包含日志的監(jiān)聽器 Logging-ApplicationListener,相關(guān)代碼如下。
# Application Listeners
org. springframework . context . ApplicationListener=\
org. springframework . boot . context. logging. LoggingApplicationListener,\當(dāng)在此注冊之后,在 SpringApplication 的構(gòu)造方法中會獲得實現(xiàn) ApplicationListener 接口的注冊監(jiān)聽器,這個監(jiān)聽器會被設(shè)置到 SpringApplication 的 listeners 屬性當(dāng)中,我們回顧一下之前的代碼。
public SpringApplication(ResourceLoader resourceLoader, Class>... primary
Sources) {
setlisteners((Collection) getSpringFactoriesInstances(ApplicationL istene
r.class));
public void setListeners(Collection extends ApplicationListener>> liste
ners) {
this.listeners = new ArrayList<>();
this. listeners . addAll(listeners);
}
在 啟 動 過 程 中 , SpringApplication 的 run 方 法 會 獲 得 spring-boot 項 目 中 在META-INF/spring.factories 配置文件中的 Run Listeners,配置如下。
# Run Listeners
rg. springframework. boot. SpringApplicationRunL istener=\
org. springframework . boot . context . event . EventPublishingRunListenerSpringApplication 的 run 方法中會獲取
SpringApplicationRunListener 接口的監(jiān)聽注冊類,相關(guān)代碼如下。
public ConfigurableApplicationContext run(String... args) {
...SpringApplicationRunL isteners listeners = getRunListeners (args);
listeners. starting();
try {
...
listeners. started(context);
.. .
} catch (Throwable ex) {
try {
//遁知監(jiān)昕器:容器正在運行
listeners. running( context);
} catch (Throwable ex) {
}
return context;
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class>[] types = new Class>[] { SpringApplication. class, String[].cla
ss };
return new SpringApplicationRunL isteners(logger, getSpringFactoriesInstan
ces(
SpringApplicationRunL istener.class, types, this, args));
}在 getRunListeners 方法中,通過
getSpringFactoriesInstances 方法 (之前章節(jié)講到過,不再贅述),獲得 spring.factories 中注冊的 SpringApplicationRunListener 接口的實現(xiàn)類集合,默認(rèn)情況下集合中只有一個 EventPublishingRunL istener 類。
然后,將包含
EventPublishingRunListener 的集合封裝到 SpringApplicationRunL isteners中 ,在 Spring Boot 啟 動過 程 的不 同 階段 會 觸發(fā) 不 同 的事 件 ,比 如 上面 代 碼中 的listeners .starting()等方法。
關(guān)于 SpringApplicationRunL isteners 的功能我們已經(jīng)學(xué)習(xí)過,當(dāng)觸發(fā)事件的方法被調(diào)用時,會遍歷監(jiān)聽器并調(diào)用對應(yīng)的方法。比如,上面調(diào)用的 listeners.starting()方法,會通過其內(nèi)部的遍歷方法,最終調(diào)用到
EventPublishingRunListener 的 starting 方法,相關(guān)源代碼如下。
class SpringApplicationRunListeners {
public void starting() {
for (SpringApplicationRunListener listener : this. listeners)
listener . starting();
}
...
EventPublishingRunListener 類是 SpringApplicationRunListener 的實現(xiàn)類,因此當(dāng)上面遍歷 調(diào) 用 SpringApplicationRunListener 的 starting 方 法 時 ,最 終 調(diào) 用 了EventPublishing-RunListener 實現(xiàn)的 starting 方法,相關(guān)代碼如下。
public class EventPublishingRunListener implements SpringApplicationRunst
ener,
Ordered {
@Override
public void starting() {
this. initialMulticaster . multicastEvent(
new
ApplicationStartingEvent(this. application, this.args));
}
}
EventPublishingRunListener 的 starting 方法會通過 SimpleApplicationEventMult-icaster 廣播一一個 ApplicationStartingEvent 事件。
該事件會觸發(fā)在構(gòu)造方法中注冊的
LoggingApplicationListener 監(jiān)聽器,進(jìn)行日志相關(guān)的邏輯處理,下面章節(jié)會對關(guān)于觸發(fā)的事件進(jìn)行詳細(xì)講解。

本文給大家講解的內(nèi)容是Spring Boot日志源碼解析:LoggingApplicationListener的觸發(fā)
下篇文章給大家講解的是Spring Boot日志源碼解析:LoggingApplicationListener的執(zhí)行;
覺得文章不錯的朋友可以轉(zhuǎn)發(fā)此文關(guān)注小編;
感謝大家的支持!
本文就是愿天堂沒有BUG給大家分享的內(nèi)容,大家有收獲的話可以分享下,想學(xué)習(xí)更多的話可以到微信公眾號里找我,我等你哦。
