10、准备应用上下文
private void prepareContext(ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
//设置环境参数
context.setEnvironment(environment);
postProcessApplicationContext(context);
//所有ApplicationContextInitializer类 初始化
applyInitializers(context);
//contextPrepared监听事件
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// 获取beanFactory 为下面注册单例bean做准备
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// Load the sources
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[0]));
//contextLoaded监听事件
listeners.contextLoaded(context);
}
public void setEnvironment(ConfigurableEnvironment environment) {
// 设置context的environment
super.setEnvironment(environment);
// 实例化context的reader属性的environment属性
this.reader.setEnvironment(environment);
// 设置context的scanner属性的environment属性
this.scanner.setEnvironment(environment);
}
this.beanNameGenerator和this.resourceLoader为空应该是扩展用的
protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
if (this.beanNameGenerator != null) {
context.getBeanFactory().registerSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
this.beanNameGenerator);
}
if (this.resourceLoader != null) {
if (context instanceof GenericApplicationContext) {
((GenericApplicationContext) context)
.setResourceLoader(this.resourceLoader);
}
if (context instanceof DefaultResourceLoader) {
((DefaultResourceLoader) context)
.setClassLoader(this.resourceLoader.getClassLoader());
}
}
}
初始化ApplicationContextInitializer,执行所有ApplicationContextInitializer类的initialize方法,赋值在SpringApplication的构造方法中
org.springframework.boot.context.config.DelegatingApplicationContextInitializer@f440ae7, org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer@5351a81e, org.springframework.boot.context.ContextIdApplicationContextInitializer@38bd9799, org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer@2884f688, org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer@7b8c24d, org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener@59f79bfc, org.springframework.boot.devtools.restart.RestartScopeInitializer@d22de04
protected void applyInitializers(ConfigurableApplicationContext context) {
for (ApplicationContextInitializer initializer : getInitializers()) {
Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(
initializer.getClass(), ApplicationContextInitializer.class);
Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
initializer.initialize(context);
}
}
context.getBeanFactory();获取beanFactory ,赋值在GenericApplicationContext类中,此类是AnnotationConfigServletWebServerApplicationContext父类
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
重点关注一下load方法,加载启动类到spring容器
一直跟进load方法会找到AnnotatedBeanDefinitionReader类的doRegisterBean方法负责注册启动类,注册通俗上来讲将启动类存入DefaultListableBeanFactory类的this.beanDefinitionMap(ConcurrentHashMap)变量中。
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
本文深入探讨了Spring Boot应用程序启动过程中的关键步骤,包括上下文准备、环境参数设置、监听事件触发、bean定义注册等核心操作。通过分析源码,揭示了Spring Boot如何初始化和配置ApplicationContext,以及如何加载和注册启动类。

被折叠的 条评论
为什么被折叠?



