//没置上下文的配置环境
context . setEnvironment (environment);
//应用上下文后置处理
postProcessApplicationContext( context);//在 context 刷新之前,Appl icat ionContext Init
ial izer 初始化 context
applyInitializers(context);
//通知监听器 context 准备完成,该方法以 上为上下文准备阶段,以下为上下文加载阶段
listeners . contextPrepared(context);//打印日志,启动 Profile
if (this . logStartupInfo)-
logStartupInfo(context . getParent() == nu1l);
logStartupProfileInfo( context);
}
//获得 ConfigurableL istableBeanFactory 并炷册单例对象
ConfigurableL istableBeanFactory beanFactory = context . getBeanFactory();
beanFactory. registerSingleton(“springApplicat ionArguments”, applicationAr
guments);
if (printedBanner != null) {
//注册打印日志对象
beanF actory. registerSingleton(“springBootBanner”, printedBanner);
if (beanFactory instanceof DefaultlistableBeanFactory) {
//没置是否允许覆盖炷册
((DefaultListableBeanFactory) beanFactory)
. setAllowBeanDefinitionOverriding(this . allowBeanDefinitionOverriding);
//获取全部配置源,其中包含 primarySources 和 sources
Set<0bject> sources = getAllSources();
Assert . notEmpty(sources, “Sources must not be empty”);
//将 sources 中的 Bean 加载到 context 中
load(context, sources . toArray(new 0bject[0]));
//遁知监听器 context 加载完成
listeners . contextLoaded(context);
}
通过流程图和具体代码可以看出,在该方法内完成了两步操作:应用上下文的准备和加载。
下面我们针对具体的源代码进行详细讲解。
应用上下文准备阶段
=========
在上下文准备阶段,主要有 3 步操作:对 context 设 置 environment、应用上下文后置处理和 ApplicationContextlnitializer 初始化 context 操作。
首先是对 context 设置 environment,代码和业务操作都很简单。
public void setEnvironment (ConfigurableEnvironment environment) {
//设置 context 的 environment
super. setEnvi ronment( environment);
//设置 context 的 reader 属性的 conditionEvaluator 属性 this.reade
er. settEnvironment(environment) ;
//设置 context 的 scanner 属性的 environment 属性
this. scanner. setEnvi ronment ( envi ronment);
}
随 后 , 便 是 进 行 Spring 应 用 上 下 文 的 后置处理 , 这 一 步 是 通 过postProcessApplicationContext 方法来完成的。
protected void postProcessApplicat ionContext (ConfigurableApplicat ionConEext
context){
f (this. beanNameGenerator != null) {
// 如果 beanNameGenerator 为 null, 则将当前的 beanNameGenerator 按照默认名字进
行注册
context . getBeanFactory(). regi sterSingleton(
Annotat ionConfigUtils .CONF IGURATION BEAN NAME GENERATOR,
this . beanNameGenerator);
esourceLoader 为 null 时, 则根据 context 的类型分别进行 Resourceloader 和 CL
assLoader 的设置
if (this .resourceLoader != null) {
F (context instanceof GenericApplicationContext) {
((GenericApplicationContext) context) . setResourcel oader(this . resource
Loader);
if (context instanceof DefaultResourceLoader) {
( (DefaultResourceLoader) context)
. setClassLoader(this.resourceLoader. getClassLoader());
//如果为 true 则获取并没置转换服务
f (this .addConversionService) {
context . getBeanFactory(). setConversionService(
ApplicationConversionService . getSharedInstance());
}
postProcessApplicationContext 方 法 主 要 完 成 上 下 文 的 后 置 操 作 , 默 认 包 含beanNameGeneratorResourceL oader.ClassL oader 和 ConversionService 的设置。该方法可由子类覆盖实现,以添加更多的操作。
而在此阶段,beanNameGenerator 和 resourceL oader 都为 null,因此只操作了最后-一步的设置转换服务。
最后,在通知监听器 context 准备完成之前,通过 applylnitializers 方法对上下文进行初始化。
所使用的 ApplicationContextInitializer 正是我们在 SpringApplication 初始化阶段设置在itializers 变量中的值,只不过在通过 getlnitializers 方法获取时进行了去重和排序。
protected void applyInitializers(ConfigurableApplicat ionContext context) {
/获取 Appl icat ionContextInitializer 集合并遍历
for (ApplicationContextInitializer initializer : getInitializers()) {
//解析当前 initial izer.实现的 Appl icat ionContextInitializer 的泛型参数
Class<?> requiredType = GenericTypeResolver . resolveTypeArgument(
initializer . getClass(), ApplicationContextInitializer.class);
1 断言判断所需类似是否与 context 类型匹配
Assert. isInstanceOf(requiredType, context, "Unable to call initialize
r.");
// 初始化 context
initializer. initialize(context);
}
}
完成以上操作之后,程序便调用 SpringApplicationRunListeners 的 contextPrepared 方法通知监听器,至此第一阶段的准备操作完成。
应用上下文加载阶段
=========
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
读者福利
分享一份自己整理好的Java面试手册,还有一些面试题pdf
不要停下自己学习的脚步
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
不要停下自己学习的脚步*
[外链图片转存中…(img-C9tjLwsl-1712765673646)]
[外链图片转存中…(img-09FijjvG-1712765673647)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-Q2xBkkYa-1712765673647)]