/**
*SpringApplication
*/
//構造器初始化
public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
this.sources = new LinkedHashSet();
//橫幅模式 OFF,CONSOLE,LOG;
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.isCustomEnvironment = false;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
//應用類型NONE,SERVLET,REACTIVE;存在DispatcherHandler,不存在DispatcherServlet,ServletContainer,則爲REACTIVE
//不存在javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext,則爲NONE,則爲SERVLET
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//spring.factories文件中org.springframework.context.ApplicationContextInitializer=\
//org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
//org.springframework.boot.context.ContextIdApplicationContextInitializer,\
//org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
//org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
//org.springframework.context.ApplicationListener=\
//org.springframework.boot.ClearCachesApplicationListener,\
//org.springframework.boot.builder.ParentContextCloserApplicationListener,\
//org.springframework.boot.context.FileEncodingApplicationListener,\
//org.springframework.boot.context.config.AnsiOutputApplicationListener,\
//org.springframework.boot.context.config.ConfigFileApplicationListener,\
//org.springframework.boot.context.config.DelegatingApplicationListener,\
//org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
//org.springframework.boot.context.logging.LoggingApplicationListener,\
//org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener 進行初始化
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
//推論出主類main
this.mainApplicationClass = this.deduceMainApplicationClass();
}
//核心開始運行
public ConfigurableApplicationContext run(String... args) {
//秒錶,用於記錄啓動時間,記錄每個任務 的時間,
StopWatch stopWatch = new StopWatch();
stopWatch.start();
//spring應用上下文,spring容器
ConfigurableApplicationContext context = null;
//自定義SpringApplication啓動錯誤的回調接口
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
//java.awt.headless模式 默認爲true開啓
this.configureHeadlessProperty();
//開啓監聽
//org.springframework.boot.SpringApplicationRunListener=\
//org.springframework.boot.context.event.EventPublishingRunListener
SpringApplicationRunListeners listeners = this.getRunListeners(args);
//
listeners.starting();
Collection exceptionReporters;
try {
//參數封裝,在命令行下啓動應用帶的參數,如--server.port
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//環境準備 1.加載外部化配置的資源到environment 2.觸發ApplicationEnvironmentPreparedEvent事件
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
//配置系統屬性spring.beaninfo.ignore
this.configureIgnoreBeanInfo(environment);
//打印橫幅
Banner printedBanner = this.printBanner(environment);
//創建ApplicationContext 根據webApplicationType
//SERVLET:
// contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
//REACTIVE:
// contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
// default:
// contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
/**
*AnnotationConfigServletWebServerApplicationContext層級關係-》ServletWebServerApplicationContext-》GenericWebApplicationContext
*-》GenericApplicationContext-》AbstractApplicationContext
*/
//部分屬性:reader、scanner、beanFactory進行了實例化
context = this.createApplicationContext();
//實例化 用來支持報告關於啓動的錯誤
//# Error Reporters
//org.springframework.boot.SpringBootExceptionReporter=\
//org.springframework.boot.diagnostics.FailureAnalyzers
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
//ApplicationContext準備 加載
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//核心:
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
//環境準備
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
//創建環境 SERVLET StandardServletEnvironment; REACTIVE StandardReactiveWebEnvironment; StandardEnvironment
ConfigurableEnvironment environment = this.getOrCreateEnvironment();
this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
listeners.environmentPrepared((ConfigurableEnvironment)environment);
this.bindToSpringApplication((ConfigurableEnvironment)environment);
if (!this.isCustomEnvironment) {
environment = (new EnvironmentConverter(this.getClassLoader())).convertEnvironmentIfNecessary((ConfigurableEnvironment)environment, this.deduceEnvironmentClass());
}
ConfigurationPropertySources.attach((Environment)environment);
return (ConfigurableEnvironment)environment;
}
/**
*AbstractApplicationContext
*/
//刷新
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
//刷新前準備 校驗
this.prepareRefresh();
//獲取DefaultListableBeanFactory實例
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//beanFactory加載配置
this.prepareBeanFactory(beanFactory);
try {
//beanFactory後置處理,重寫ApplicationContext的postProcessBeanFactory方法
this.postProcessBeanFactory(beanFactory);
//核心:
this.invokeBeanFactoryPostProcessors(beanFactory);
//註冊BeanPostProcessor
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
springboot啓動源碼解析
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.