天天看点

SpringBoot启动过程(二)

​​上一篇 ​​https://blog.51cto.com/u_15815563/5787667​​

说到设置了初始化器。

设置listener

现在,同样的一套流程,这次要实例化的是实现了ApplicationListener的类,并存入listeners变量。

按照order排序,下面列出各个监听器的优先级顺序

第一,RestartApplicationListener, order=HIGHEST_PRECEDENCE=-2147483648,最高优先级。

第二,BootstrapApplicationListener,order=Ordered.HIGHEST_PRECEDENCE + 5 = -2147483643

第三,LoggingSystemShutdownListener,BootstrapApplicationListener.DEFAULT_ORDER + 1; 第二的顺序+1

第四,ConfigFileApplicationListener, Ordered.HIGHEST_PRECEDENCE + 10;

第五,AnsiOutputApplicationListener,ConfigFileApplicationListener.DEFAULT_ORDER + 1

第六,LoggingApplicationListener,Ordered.HIGHEST_PRECEDENCE + 20

第七,ClasspathLoggingApplicationListener,LoggingApplicationListener.DEFAULT_ORDER + 1

第八,BackgroundPreinitializer,LoggingApplicationListener.DEFAULT_ORDER + 1 (和第七是一样的大小)

第九,RestartListener, order=0

第十,DelegatingApplicationListener, order=0

第十一,ParentContextCloserApplicationListener, order=Ordered.LOWEST_PRECEDENCE - 10

第十二,DevToolsLogFactory.Listener ,无order设置,默认最低

第十三,ClearCachesApplicationListener,无order设置,默认最低

第十四,FileEncodingApplicationListener,显式最低,Ordered.LOWEST_PRECEDENCE

第十五,LiquibaseServiceLocatorApplicationListener,无order设置,默认最低

最后四个,都是最低优先级,有的没有设置,有的设置了是最低。

前八个多是SpringBoot系统级别的第一级别优先级梯队,都是很小的复数。

设置mainApplicationClass

在实例化的最后一步,是判断,运行main方法的主类。

方法如下

private Class<?> deduceMainApplicationClass() {
    try {
      StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
      for (StackTraceElement stackTraceElement : stackTrace) {
        if ("main".equals(stackTraceElement.getMethodName())) {
          return Class.forName(stackTraceElement.getClassName());
        }
      }
    }
    catch (ClassNotFoundException ex) {
      // Swallow and continue
    }
    return null;
  }      

通过遍历堆栈,如果方法名是 main,就判定为启动的类。

至此,SpringApplication实例化结束。