SpringBoot2.0之SpringApplication源碼分析

此源碼分析針對於SpringBoot的2.0.1.RELEASE版本

一、首先我們先看到啓動類中

在這裏插入圖片描述

二、點擊進入SpringApplication的run方法

在這裏插入圖片描述
由此可以看出SpringApplication.run(AppWeiXin.class, args);實際上是返回的有對象的。即ConfigurableApplicationContext

三、繼續進入run方法

在這裏插入圖片描述
由此我們可以知道

ConfigurableApplicationContext run = SpringApplication.run(AppWeiXin.class, args);
//其實就等於
ConfigurableApplicationContext run = new SpringApplication(AppWeiXin.class).run(args);
四、繼續進入SpringApplication

在這裏插入圖片描述
可以知道,SpringApplication的有參構造方法再次調用了它的重載有參構造方法

五、然後我們看到上面大紅框中的this.webApplicationType = deduceWebApplicationType();,進入deduceWebApplicationType方法

在這裏插入圖片描述
點擊進入ClassUtil.isPresent方法中,同時進入REACTIVE_WEB_ENVIRONMENT_CLASS等幾個常量中,我們可以知道deduceWebApplicationType就是判斷是否爲web應用,通過classLoader判斷是否加載的有以下三個類

	public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
			+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";

	private static final String REACTIVE_WEB_ENVIRONMENT_CLASS = "org.springframework."
			+ "web.reactive.DispatcherHandler";

	private static final String MVC_WEB_ENVIRONMENT_CLASS = "org.springframework."
			+ "web.servlet.DispatcherServlet";

然後我進入WebApplicationType中,看到NONE,SERVLET,REACTIVE三種枚舉常量,查看官方文檔官方文檔可知:
在這裏插入圖片描述

六、看到四中的setInitializers((Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class));

我們可以先看(Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class),它其實就是從類路徑下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;然後再將其保存到List<ApplicationListener<?>>中
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

七、看到四中的setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));,原理同六

它是從類路徑下找到META-INF/spring.factories配置的所有ApplicationListener

八、然後獲取Main函數主類
this.mainApplicationClass = deduceMainApplicationClass();
九、SpringBoot的run方法說明
public ConfigurableApplicationContext run(String... args) {
 // 構造一個任務執行觀察器
   StopWatch stopWatch = new StopWatch();
// 開始執行,記錄開始時間
   stopWatch.start();
// 聲明IOC容器
   ConfigurableApplicationContext context = null;
   Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
   configureHeadlessProperty();
// 獲取SpringApplicationRunListeners,內部只有一個EventPublishingRunListener
   SpringApplicationRunListeners listeners = getRunListeners(args);
    //回調所有的獲取SpringApplicationRunListener.starting()方法
 listeners.starting();
   try {
  // 構造一個應用程序參數持有類
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(
            args);
  // 參數環境配置
      ConfigurableEnvironment environment = prepareEnvironment(listeners,
            applicationArguments);
      configureIgnoreBeanInfo(environment);
// 打印啓動信息
      Banner printedBanner = printBanner(environment);
      context = createApplicationContext();
      exceptionReporters = getSpringFactoriesInstances(
            SpringBootExceptionReporter.class,
            new Class[] { ConfigurableApplicationContext.class }, context);
      prepareContext(context, environment, listeners, applicationArguments,
            printedBanner);
      refreshContext(context);
      afterRefresh(context, applicationArguments);
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass)
               .logStarted(getApplicationLog(), stopWatch);
      }
      listeners.started(context);
      callRunners(context, applicationArguments);
   }
   catch (Throwable ex) {
      handleRunFailure(context, listeners, exceptionReporters, ex);
      throw new IllegalStateException(ex);
   }
   listeners.running(context);
   return context;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章