天天看點

SpringBoot啟動過程(三)

在執行個體化SpringApplication後,緊接着執行其run方法

執行個體化SpringApplicationRunListener接口的實作,隻找到

EventPublishingRunListener 一個類。

EventPublishingRunListener 這個類主要是 釋出 應用的各個階段的狀态。

private final SimpleApplicationEventMulticaster initialMulticaster;

public EventPublishingRunListener(SpringApplication application, String[] args) {
   this.application = application;
   this.args = args;
   this.initialMulticaster = new SimpleApplicationEventMulticaster();
   for (ApplicationListener<?> listener : application.getListeners()) {
      this.initialMulticaster.addApplicationListener(listener);
   }
}      

EventPublishingRunListener 内部有一個 事件廣播器 initialMulticaster

在上一步 執行個體化的listerner都會放入這個 事件廣播器中,後面會向它們廣播響應的事件。

在EventPublishingRunListener 執行個體化後,馬上會調用 starting方法,如下

listeners.starting();      

這個方法,就是釋出第一個事件 ApplicationStartingEvent

@Override
public void starting() {
   this.initialMulticaster.multicastEvent(
         new ApplicationStartingEvent(this.application, this.args));
}      

先過濾出,所有處理這個事件的listener, 這次啟動一共4個,分别為

LoggingApplicationListener
BackgroundPreinitializer
DelegatingApplicationListener
LiquibaseServiceLocatorApplicationListener      

然後,請求doInvokeListener, 讓這些listener,去響應這個事件。

對具體的listener,是調用它的 onApplicationEvent 方法,對具體Event進行處理。

下面分别介紹一下,這裡每一個listener,對這個 ApplicationStartingEvent  事件的處理。

日志 LoggingApplicationListener

首先判斷,用的是什麼日志系統 ,儲存于變量loggingSystem中

static {
    Map<String, String> systems = new LinkedHashMap<>();
    systems.put("ch.qos.logback.core.Appender",
        "org.springframework.boot.logging.logback.LogbackLoggingSystem");
    systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory",
        "org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");
    systems.put("java.util.logging.LogManager",
        "org.springframework.boot.logging.java.JavaLoggingSystem");
    SYSTEMS = Collections.unmodifiableMap(systems);
  }      

程式,會在類加載器中,找上面這些類是否存在,并選出第一個,作為日志系統,可以看出,springboot 是推薦使用logback的,放在第一位。

正好有引用logback,是以,選擇出來使用的系統是 

org.springframework.boot.logging.logback.LogbackLoggingSystem

背景預初始化BackgroundPreinitializer

public void run() {
   runSafely(new ConversionServiceInitializer());
   runSafely(new ValidationInitializer());
   runSafely(new MessageConverterInitializer());
   runSafely(new MBeanFactoryInitializer());
   runSafely(new JacksonInitializer());
   runSafely(new CharsetInitializer());
   preinitializationComplete.countDown();
}      

在這裡,會對 執行個體化以上的 類。

DelegatingApplicationListener

對starting這個事件,沒有具體工作。

LiquibaseServiceLocatorApplicationListener 沒有效果