天天看点

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 没有效果