- ">
- 实例化SpringApplication
- 执行run方法
- getRunListeners(args);
- 【事件】listeners.starting();
- prepareEnvironment
- createApplicationContext();
- prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
- 【applicationContext.refresh()】refreshContext(context);
- 【事件】listeners.started(context);
- 【ApplicationRunner】callRunners(context, applicationArguments);
- 【事件】listeners.running(context);
实例化SpringApplication
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = deduceWebApplicationType();
// 使用SpringFactoriesLoader.loadFactoryNames(SPI)来获取设置ApplicationContextInitializer类名
// 使用BeanUtils.instantiateClass 来构造设置ApplicationContextInitializer对象
// 设置ApplicationContextInitializer 到 SpringApplication.initializers 属性中
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//用同样的方式加载 ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 设置main方法所在的类。
this.mainApplicationClass = deduceMainApplicationClass();
}
加载ApplicationContextInitializer
- SPI获取ApplicationContextInitializer
设置ApplicationContextInitializer到SpringApplication
加载ApplicationListener
用同样的方式加载 ApplicationListener
SpringApplicationRunListeners
public ConfigurableApplicationContext run(String… args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Collection
exceptionReporters = new ArrayList<>(); configureHeadlessProperty(); //获取 SpringApplicationRunListener ,扩展点,用得少
SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(); try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
//创建Environment,web和app创建类型不一样
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
//创建ApplicationContext,
//web=AnnotationConfigEmbeddedWebApplicationContext
//app=AnnotationConfigApplicationContext
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//执行ApplicationContextInitializer initialize() 方法
//执行SpringApplicationRunListener.contextPrepared()
//注入ApplicationArguments对象
//加载source到context中
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//调用context.refresh(),这就转到spring内部管理实例化bean等操作
refreshContext(context);
//回调ApplicationRunner、ConmmandLineRunner(开机自启动)
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
} catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
} catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
} return context; }
getRunListeners(args);
【事件】listeners.starting();
prepareEnvironment
创建Environment
【事件】listeners.environmentPrepared(bootstrapContext, environment);
ConfigFileApplicationListener监听
ConfigFileApplicationListener#onApplicationEnvironmentPreparedEvent
执行EnvironmentPostProcessor#postProcessEnvironment
获取placeholdersResolver、resourceLoader、propertySourceLoaders
解析配置文件
spring cloud加载配置文件:BootstrapApplicationListener
绑定spring.main到SpringApplication
createApplicationContext();
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
applyInitializers(context);
DelegatingApplicationContextInitializer
- ConfigDataEnvironmentPostProcessor负责读取application.properties,加载到Environment。
【事件】listeners.contextPrepared(context);
加载BeanDefinition
【事件】listeners.contextLoaded(context);