SpringApplication启动流程六
2023-05-01 本文已影响0人
程序员札记
初始化基本流程
SpringApplication的prepareEnvironment准备环境
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
// Create and configure the environment
ConfigurableEnvironment environment = getOrCreateEnvironment();//获取环境
configureEnvironment(environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach(environment);//ConfigurationPropertySources附加到环境一次
listeners.environmentPrepared(environment);//广播环境准备好的事件
bindToSpringApplication(environment);//绑定到SpringApplication
if (!this.isCustomEnvironment) {
environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
deduceEnvironmentClass());//推断环境,如果不是这个类型,要进行切换
}
ConfigurationPropertySources.attach(environment);//又附加一次,主要是为了放最前面
return environment;
}
SpringApplication的getOrCreateEnvironment创建环境
根据前面的webApplicationType判断要创建哪种环境。
private ConfigurableEnvironment getOrCreateEnvironment() {
if (this.environment != null) {
return this.environment;
}
switch (this.webApplicationType) {
case SERVLET:
return new StandardServletEnvironment();
case REACTIVE:
return new StandardReactiveWebEnvironment();
default:
return new StandardEnvironment();
}
}
configureEnvironment配置环境
这里主要是配置了很多的类型转换器和格式转换器,另外两个跟换进属性相关
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
if (this.addConversionService) {
ConversionService conversionService = ApplicationConversionService.getSharedInstance();//配置转换器
environment.setConversionService((ConfigurableConversionService) conversionService);//设置到环境中去
}
configurePropertySources(environment, args);//配置默认属性
configureProfiles(environment, args);//配置代码添加的环境
}
ApplicationConversionService的getSharedInstance配置转换器
这个里面有配置很多转换器,我就不多讲了,自己看就行了。
image.png image.png
其他剩下的暂时不讲,因为比较复杂,很多都是一些属性的配置,比如会获取你的spring.profiles.active信息,而且是ConfigFileApplicationListener收到环境准备好的事件后做的事,当然还有其他的一些配置信息,我们还是先把主线弄明白再搞细节,不过这里配置完成会进行广播,这次的事件是ApplicationEnvironmentPreparedEvent:
image.pngSpringApplication的printBanner打印banner
内部支持 "gif", "jpg", "png","txt":
image.png
默认把资源放到resources下,名字为banner.xxx就可以了,自己可以去试试:
image.png
我们经常看到的默认的在这里面:
image.png
createApplicationContext创建上下文
根据类型创建对应的上下文对象,默认全是注解
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET://AnnotationConfigServletWebServerApplicationContext
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE://AnnotationConfigReactiveWebServerApplicationContext
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default://AnnotationConfigApplicationContext
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
image.png
准备环境这里比较复杂,准备完了就是spring的核心refresh了。