1、SpringApplication new一個對象會優先調用initialize方法
public SpringApplication(Object... sources) {initialize(sources); }
private void initialize(Object[] sources) {//添加配置類@SpringBootApplicationif (sources != null && sources.length > 0) {this.sources.addAll(Arrays.asList(sources));}//判斷是不是運行在web環境中this.webEnvironment = deduceWebEnvironment();//從spring.factories加載出所有實現org.springframework.context.ApplicationContextInitializer初始化器,并且通過反射創建實例//Tomcat ---org.springframework.boot.web.servlet.support.ServletContextApplicationContextInitializersetInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));//從spring.factories中org.springframework.context.ApplicationListener找到配置類,并且反射創建實例。setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));//確認入口類,通常是這種/* public static void main(String[] args) {** SpringApplication.run(DemoApplication.class, args);** }*/this.mainApplicationClass = deduceMainApplicationClass();
}
?2、確認入口類之后,就是SpringApplication.run(XXXXApplication.class, args);的調用了。
/*** Run the Spring application, creating and refreshing a new* {@link ApplicationContext}.* @param args the application arguments (usually passed from a Java main method)* @return a running {@link ApplicationContext}*/public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;FailureAnalyzers analyzers = null;configureHeadlessProperty();//獲取應用運行監聽器,并觸發開始事件SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();try {//創建應用參數對象ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);// 準備環境,包括配置文件和屬性源ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);//打印應用的 BannerBanner printedBanner = printBanner(environment);//獲取當前ConfigurableApplicationContext應用上下文。context = createApplicationContext();//獲取失敗分析器analyzers = new FailureAnalyzers(context);// 準備上下文,包括加載 bean 定義prepareContext(context, environment, listeners, applicationArguments,printedBanner);//調用spring refresh 方法refreshContext(context);//refresh的后置處理afterRefresh(context, applicationArguments);//通知所有基于SpringApplicationRunListeners回調完成。listeners.finished(context, null);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}return context;}catch (Throwable ex) {handleRunFailure(context, listeners, analyzers, ex);throw new IllegalStateException(ex);}}private void prepareContext(ConfigurableApplicationContext context,ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments, Banner printedBanner) {//ConfigurableApplicationContext綁定一個environment,環境參數context.setEnvironment(environment);//2、application的后置處理postProcessApplicationContext(context);//3、ConfigurableApplicationContext綁定ApplicationContextInitializerapplyInitializers(context);//4、通知監聽器ConfigurableApplicationContext準備工作已完成listeners.contextPrepared(context);if (this.logStartupInfo) {logStartupInfo(context.getParent() == null);logStartupProfileInfo(context);}// Add boot specific singleton beans//向ConfigurableApplicationContext添加特定的單例Beancontext.getBeanFactory().registerSingleton("springApplicationArguments",applicationArguments);if (printedBanner != null) {context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);}// Load the sources//加載配置BeanSet<Object> sources = getSources();Assert.notEmpty(sources, "Sources must not be empty");//ConfigurableApplicationContext綁定配置Bean 并且轉化為BD。load(context, sources.toArray(new Object[sources.size()]));//通知監聽器ConfigurableApplicationContext加載完成listeners.contextLoaded(context);}