1 public ConfigurableApplicationContext run(String... args) { 2 StopWatch stopWatch = new StopWatch(); //設置計時器 3 stopWatch.start(); //記錄當前時間 4 ConfigurableApplicationContext context = null; 5 configureHeadlessProperty(); //設置java.awt.headless為true或false 6 SpringApplicationRunListeners listeners = getRunListeners(args);//獲取事件發布器(控制所有事件的執行時機) 7 listeners.started(); //事件發布器發布ApplicationStartedEvent事件,所有監聽了該事件的ApplicationListener實現類執行邏輯 8 try { 9 context = doRun(listeners, args); 10 stopWatch.stop(); //計時結束(記錄總共花了多少時間) 11 if (this.logStartupInfo) { 12 new StartupInfoLogger(this.mainApplicationClass) 13 .logStarted(getApplicationLog(), stopWatch); 14 } 15 return context; 16 } 17 catch (Throwable ex) { 18 handleRunFailure(context, listeners, ex); 19 throw new IllegalStateException(ex); 20 } 21 }
1 private ConfigurableApplicationContext doRun(SpringApplicationRunListeners listeners, 2 String... args) { 3 ConfigurableApplicationContext context; 4 // Create and configure the environment 5 ConfigurableEnvironment environment = getOrCreateEnvironment(); //創建Environment 6 configureEnvironment(environment, args); //配置Environment(包括配置要使用的PropertySource和Profile) 7 listeners.environmentPrepared(environment); //事件發布器發布ApplicationEnvironmentPreparedEvent事件,所有監聽了該事件的ApplicationListener執行相應邏輯 8 if (isWebEnvironment(environment) && !this.webEnvironment) { 9 environment = convertToStandardEnvironment(environment); 10 } 11 12 if (this.bannerMode != Banner.Mode.OFF) { 13 printBanner(environment); 14 } 15 16 // Create, load, refresh and run the ApplicationContext 17 context = createApplicationContext(); //創建ApplicationContext容器 18 context.setEnvironment(environment); //設置Environment到容器 19 postProcessApplicationContext(context); 20 applyInitializers(context); //執行所有的ApplicationContextInitializer的initial方法,對創建出來的ApplicationContext容器進行初始化 21 listeners.contextPrepared(context); 22 if (this.logStartupInfo) { 23 logStartupInfo(context.getParent() == null); 24 logStartupProfileInfo(context); 25 } 26 27 // Add boot specific singleton beans 28 ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); 29 context.getBeanFactory().registerSingleton("springApplicationArguments", 30 applicationArguments); 31 32 // Load the sources 33 Set<Object> sources = getSources(); 34 Assert.notEmpty(sources, "Sources must not be empty"); 35 load(context, sources.toArray(new Object[sources.size()])); //將之前通過@EnableAutoConfiguration的所有配置以及其他形式的IOC容器加載到已經准備完畢的ApplicationContext 36 listeners.contextLoaded(context); //事件發布器將所有的ApplicationListener注冊給當前的ApplicationContext,之後發布ApplicationPreparedEvent事件 37 38 // Refresh the context 39 refresh(context); //刷新ApplicationContext 40 if (this.registerShutdownHook) { 41 try { 42 context.registerShutdownHook(); 43 } 44 catch (AccessControlException ex) { 45 // Not allowed in some environments. 46 } 47 } 48 afterRefresh(context, applicationArguments); 49 listeners.finished(context, null); 50 return context; 51 }
步驟總結:
以上紅色部分就是核心步驟!
參考:
http://www.jianshu.com/p/692b10aef052
http://zhaox.github.io/java/2016/03/22/spring-boot-start-flow
《springboot揭秘-快速構建微服務體系》