程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 附4 springboot源碼解析-run(),springboot-run

附4 springboot源碼解析-run(),springboot-run

編輯:JAVA綜合教程

附4 springboot源碼解析-run(),springboot-run


 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     }

 步驟總結:

  • 設置計時器,記錄當前時間
    • 該類是一個非線程的安全的,如果自己使用要考慮多線程的情況.
  • 設置java.awt.headless為true或false
    • java.awt.headless是J2SE的一種模式用於在缺少顯示屏、鍵盤或者鼠標時的系統配置,很多監控工具如jconsole 需要將該值設置為true
  • 獲取事件發布器(用於控制所有事件的執行時機)
  • 事件發布器發布ApplicationStartedEvent事件,所有監聽了該事件的ApplicationListener實現類執行邏輯
  • 創建並配置Environment(包括配置要使用的PropertySource和Profile)
    • PropertySource主要是讀取SpringApplication.setDefaultProperties指定的默認屬性 + 命令行屬性
    • Profile主要是讀取application-{level}.properties以及application.properties中的內容
    • 關於配置文件的一系列問題 見附 5 springboot之配置文件
  • 事件發布器發布ApplicationEnvironmentPreparedEvent事件,所有監聽了該事件的ApplicationListener執行相應邏輯
  • 創建ApplicationContext容器
  • 設置Environment到容器
  • 執行所有的ApplicationContextInitializer的initial方法,對創建出來的ApplicationContext容器進行初始化
  • 將之前通過@EnableAutoConfiguration的所有配置以及其他形式的IOC容器加載到已經准備完畢的ApplicationContext
    • 裝載beanDefinition到ApplicationContext(之後在使用Bean的時候,直接由beanDefinition初始化為bean)
  • 事件發布器將所有的ApplicationListener注冊給當前的ApplicationContext,之後發布ApplicationPreparedEvent事件
  • 刷新ApplicationContext
    • 這裡如果有ContextRefreshedEvent的監聽器,那麼此時就會觸發其onApplication方法
  • 結束計時,記錄整個啟動時間

以上紅色部分就是核心步驟!

 

參考:

http://www.jianshu.com/p/692b10aef052

http://zhaox.github.io/java/2016/03/22/spring-boot-start-flow

《springboot揭秘-快速構建微服務體系》

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved