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揭秘-快速構建微服務體系》