springboot1.5.10應用啓動原理

一、springboot應用啓動源碼分析

 public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
        return (new SpringApplication(sources)).run(args);
 }

【1】創建SpringApplication對象

調用initialize(sources);創建對象。流程:

private void initialize(Object[] sources) {
   //1.保存主配置類
   if(sources != null && sources.length > 0) {
		this.sources.addAll(Arrays.asList(sources));
   }
  
   //2.判斷當前應用是否是一個web應用
  this.webEnvironment = deduceWebEnvironment();
  //3.從類路徑下找到META-INF/spring.factories配置的所有ApplicationContextInitializer,然後保存起來
  setInitializers((Collection) getSpringFactoriesInstances(
		ApplicationContextInitializer.class));
  //4.從類路徑下找到META-INF/spring.factories配置的所有ApplicationListener
  setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
  //5.從多個配置類中找到含有"main"的主配置類
  this.mainApplicationClass = deduceMainApplicationClass();
}

有6個initializer:
在這裏插入圖片描述

可以找到的ApplicationListener:
在這裏插入圖片描述

【2】運行run方法

public ConfigurableApplicationContext run(String... args) {
	StopWatch stopWatch = new StopWatch();
	stopWatch.start();
	ConfigurableApplicationContext context = null;
	FailureAnalyzers analyzers = null;
	configureHeadlessProperty();
	//從類路徑下下META‐INF/spring.factories獲取SpringApplicationRunListener
	SpringApplicationRunListeners listeners = getRunListeners(args);
	//回調獲取到的所有SpringApplicationRunListener對象的starting()方法
	listeners.starting();
	try {
	    //封裝命令行參數
		ApplicationArguments applicationArguments = new DefaultApplicationArguments(
				args);
		//準備環境。創建環境完成後回調SpringApplicationRunListener.environmentPrepared()方法,表示環境已經準備完成
		ConfigurableEnvironment environment = prepareEnvironment(listeners,
				applicationArguments);
		//打印springboot的圖標
		Banner printedBanner = printBanner(environment);


        //創建ApplicationContext容器:決定創建的是web的ioc容器還是普通的ioc容器
		context = createApplicationContext();
		//出現異常以後做異常分析報告的
		analyzers = new FailureAnalyzers(context);
		
		//準備上下文環境:將environment保存到ioc容器中;而且執行applyInitializers()方法; 
		//applyInitializers():回調之前保存的所有的ApplicationContextInitializer的initialize方法;回調所有的//SpringApplicationRunListener的contextPrepared();
		prepareContext(context, environment, listeners, applicationArguments,
				printedBanner);
        ///prepareContext運行完成以後回調所有的SpringApplicationRunListener的contextLoaded();

//刷新容器:即ioc容器初始化的過程(如果是web應用,還會創建嵌入式的servlet容器)。
//掃描、加載、創建所有組件的地方
		refreshContext(context);
		
       //從ioc容器中獲取所有的ApplicationRunner和CommandLineRunner進行回調 
      //ApplicationRunner先回調,CommandLineRunner再回調
		afterRefresh(context, applicationArguments);
		//所有的SpringApplicationRunListener回調finished方法
		listeners.finished(context, null);
		stopWatch.stop();
		if (this.logStartupInfo) {
			new StartupInfoLogger(this.mainApplicationClass)
					.logStarted(getApplicationLog(), stopWatch);
		}
		//整個SpringBoot應用啓動完成以後返回啓動的ioc容器
		return context;
	}
	catch (Throwable ex) {
		handleRunFailure(context, listeners, analyzers, ex);
		throw new IllegalStateException(ex);
	}
}

二、springboot應用啓動原理總結

SpringApplication.run(主程序類):

– new SpringApplication(主程序類)
  • 判斷是否web應用
  • 加載並保存所有ApplicationContextInitializer(META-INF/spring.factories)
  • 加載並保存所有ApplicationListener
  • 獲取到主程序類

– run()
 • 回調所有的SpringApplicationRunListener(META-INF/spring.factories)的starting
 • 獲取ApplicationArguments
• 準備環境&回調所有監聽器( SpringApplicationRunListener )environmentPrepared
 • 打印banner信息
 • 創建ioc容器對象(
  –AnnotationConfigEmbeddedWebApplicationContext(web環境容器)
  – AnnotationConfigApplicationContext(普通環境容器)
 • 準備環境
  – 執行ApplicationContextInitializer. initialize()
  – 監聽器SpringApplicationRunListener回調contextPrepared
  – 加載主配置類定義信息
  – 監聽器SpringApplicationRunListener回調contextLoaded
• 刷新啓動IOC容器;
  – 掃描加載所有容器中的組件
  – 包括從META-INF/spring.factories中獲取的所有EnableAutoConfiguration組件
• 回調容器中所有的ApplicationRunnerCommandLineRunnerrun方法
• 監聽器SpringApplicationRunListener回調finished

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章