springboot源码学习04-prepareContext()方法讲解

private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
//设置环境
context.setEnvironment(environment);
//上下文后处理
postProcessApplicationContext(context);
//初始化器执行 就是我们最初取出来放到springApplication.initializers中
//初始化器有很多 看下面的详细分析
applyInitializers(context);
//监听器执行
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 向beanFactory注册单例 关于参数的bean
beanFactory.registerSingleton(“springApplicationArguments”, applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton(“springBootBanner”, printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// 获取全部资源
Set sources = getAllSources();
Assert.notEmpty(sources, “Sources must not be empty”);
//这个操作我们看下面的详情
load(context, sources.toArray(new Object[0]));
// 向上下文中添加ApplicationListener,并广播ApplicationPreparedEvent事件
listeners.contextLoaded(context);
}

初始化器有几个:
在这里插入图片描述
load(context, sources.toArray(new Object[0])) 方法详情:

BeanDefinitionLoader对象里面封装了AnnotatedBeanDefinitionReader,XmlBeanDefinitionReader和ClassPathBeanDefinitionScanner 。这三个类是用来读取bean的。

Class用AnnotatedBeanDefinitionReader处理
Resource用XmlBeanDefinitionReader处理
Package用ClassPathBeanDefinitionScanner处理

通过debug跟踪到方法里面 我们发现 目前我们的source只有一个:class 就是我们的启动引导类,是class类型;先判断引导类是否有被component注解修饰,很显然是(SpringBootApplication注解中包含component注解),那么AnnotatedBeanDefinitionReader来处理:将 启动引导类 封装成一个名叫 { 启动引导类名称} 的BeanDefinition对象,并将其注册到了beanFactory的BeanDefinitionMap中。

listeners.contextLoaded(context) 方法详解:
在这里插入图片描述

事件传播 :
ConfigFileApplicationListener 向context注册了一个BeanFactoryPostProcessor(PropertySourceOrderingPostProcessor)实例;该实例后面会对我们的property sources进行重排序,另外该实例拥有上下文的引用。

LoggingApplicationListener向beanFactory中注册了一个名叫springBootLoggingSystem的单例bean,也就是我们的日志系统bean。

BackgroundPreinitializer 目前什么也没做

DelegatingApplicationListener 目前什么也没做

一般一个单例对象注册到beanFactory中,beanFactory会有2个属性都添加此单例对象信息:singletonObjects、registeredSingletons

Map<String, Object> singletonObjects = new ConcurrentHashMap<>(),key是bean name,value是单例对象

Set registeredSingletons = new LinkedHashSet<>(),存放的是bean name

一般一个 bean定义 注册到beanFactory中是,beanFactory也会有2个属相会添加此bean定义信息:beanDefinitionMap、beanDefinitionNames

List beanDefinitionNames = new ArrayList<>(),beanDefinition的名称列表
Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(),key是beanDefinition的名称,value是beanDefinition对象

另外beanFactory中Set manualSingletonNames = new LinkedHashSet<>,按注册顺序存放手动注册的单例的名称。

本文参考子:https://www.cnblogs.com/youzhibing/p/9697825.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值