SpringApplication.run
在应用启动类中调用SpringApplication.run方法,最终会new一个SpringApplication实例,再调用实例的run方法
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return (new SpringApplication(primarySources)).run(args);
}实例化SpringApplication
先看一下实例化SpringApplication过程
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
// 将启动类设置为primarySources
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 推断web应用类型,判断是webFlux还是servlet
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 从spring.factories中读取BootstrapRegistryInitializer并赋值给bootstrapRegistryInitializers(读取结果会缓存到一个Map中,避免重复读取)
this.bootstrapRegistryInitializers = new ArrayList<>(
getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
// 从spring.factories中读取ApplicationContextInitializer并赋值给initializers
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 从spring.factories中读取ApplicationListener并赋值给listeners
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 根据栈信息推断Main方法所在的类
this.mainApplicationClass = deduceMainApplicationClass();
}SpringApplication实例对象的run方法
启动整体流程在run方法中,逐行添加注释说明
public ConfigurableApplicationContext run(String... args) {
Startup startup = SpringApplication.Startup.create();
if (this.registerShutdownHook) {
shutdownHook.enableShutdownHookAddition();
}
// 创建DefaultBootstrapContext启动器,在其中会遍历执行bootstrapRegistryInitializers(没有默认实现,是SpringBoot提供的扩展点)
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
ConfigurableApplicationContext context = null;
// 设置headless模式
this.configureHeadlessProperty();
// 获取运行监听器的组件
SpringApplicationRunListeners listeners = this.getRunListeners(args);
// 执行监听器,发布事件ApplicationStartingEvent
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
// 获取应用参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 预初始化环境:读取环境变量,读取配置文件信息(基于监听器)
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
// 打印banner
Banner printedBanner = this.printBanner(environment);
// 创建容器上下文AnnotationConfigServletWebServerApplicationContext
context = this.createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
// 预初始化上下文
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 刷新上下文,最后会调用spring容器的refresh方法
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
startup.started();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), startup);
}
listeners.started(context, startup.timeTakenToStarted());
this.callRunners(context, applicationArguments);
} catch (Throwable ex) {
throw this.handleRunFailure(context, ex, listeners);
}
try {
if (context.isRunning()) {
listeners.ready(context, startup.ready());
}
return context;
} catch (Throwable ex) {
throw this.handleRunFailure(context, ex, (SpringApplicationRunListeners)null);
}
}prepareEnvironment方法
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
// Create and configure the environment
// 根据webApplicationType创建Environment,创建时会读取java环境变量和系统环境变量
ConfigurableEnvironment environment = getOrCreateEnvironment();
// 将命令行参数读取到环境变量中
configureEnvironment(environment, applicationArguments.getSourceArgs());
// 将@PropertiesSource的配置放在第一位,因为读取配置文件@PropertiesSource优先级是最低的
ConfigurationPropertySources.attach(environment);
// 发布事件ApplicationEnvironmentPreparedEvent,SpringBoot内置监听器EnvironmentPostProcessorApplicationListener监听该事件读取配置文件信息
listeners.environmentPrepared(bootstrapContext, environment);
DefaultPropertiesPropertySource.moveToEnd(environment);
Assert.state(!environment.containsProperty("spring.main.environment-prefix"),
"Environment prefix cannot be set via properties.");
// 将spring.main开头的配置信息绑定到SpringApplication
bindToSpringApplication(environment);
if (!this.isCustomEnvironment) {
EnvironmentConverter environmentConverter = new EnvironmentConverter(getClassLoader());
environment = environmentConverter.convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
}
// 更新@PropertiesSource
ConfigurationPropertySources.attach(environment);
return environment;
}prepareContext方法
private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
context.setEnvironment(environment);
postProcessApplicationContext(context);
addAotGeneratedInitializerIfNecessary(this.initializers);
// 执行Initializers
applyInitializers(context);
// 发布事件ApplicationContextInitializedEvent
listeners.contextPrepared(context);
// 发布事件BootstrapContextClosedEvent
bootstrapContext.close(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
// 获取beanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 将applicationArguments注册成一个单例bean
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof AbstractAutowireCapableBeanFactory autowireCapableBeanFactory) {
autowireCapableBeanFactory.setAllowCircularReferences(this.allowCircularReferences);
if (beanFactory instanceof DefaultListableBeanFactory listableBeanFactory) {
// 设置不允许bean定义覆盖 listableBeanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
}
// 设置是否懒加载
if (this.lazyInitialization) {
// 添加BeanFactory后置处理器
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
if (this.keepAlive) {
// 添加ApplicationListener
context.addApplicationListener(new KeepAlive());
}
// 添加BeanFactory后置处理器
context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));
if (!AotDetector.useGeneratedArtifacts()) {
// Load the sources
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
// 读取启动类(后续要根据配置类解析配置的所有bean)
load(context, sources.toArray(new Object[0]));
}
// 发布事件ApplicationPreparedEvent
listeners.contextLoaded(context);
}