Spring源码 12 IOC refresh方法7
本文章基于 Spring 5.3.15
Spring IOC 的核心是
AbstractApplicationContext
的refresh
方法。
其中一共有 13 个主要方法,这里分析第 7 个:initMessageSource
。
1 AbstractApplicationContext
1-1 初始化 message 源
initMessageSource()
protected void initMessageSource() {
// 获取 Bean 工厂
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
// 如果在配置中已经配置了 messageSource,那么将 messageSource 提取并记录在 this.messageSource 中
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
} else {
// 如果用户并没有定义配置文件,那么使用临时的 DelegatingMessageSource 以便于作为调用 getMessage 方法的返回
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
// 注册单例
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
1-2 获取 Bean 工厂
getBeanFactory()
2 AbstractRefreshableApplicationContext
public final ConfigurableListableBeanFactory getBeanFactory() {
DefaultListableBeanFactory beanFactory = this.beanFactory;
if (beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext");
}
return beanFactory;
}
if (beanFactory == null)
由于 beanFactory 已经被赋值,直接返回。
1 AbstractApplicationContext
1-2 注册单例
registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)
3 DefaultListableBeanFactory
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
// 调用父类方法
super.registerSingleton(beanName, singletonObject);
// 手动更新单例名称
updateManualSingletonNames(set -> set.add(beanName), set -> !this.beanDefinitionMap.containsKey(beanName));
// 按类型清除缓存
clearByTypeCache();
}
3-1 调用父类方法
super.registerSingleton(beanName, singletonObject)
4 DefaultSingletonBeanRegistry
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "Bean name must not be null");
Assert.notNull(singletonObject, "Singleton object must not be null");
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
// 添加单例
addSingleton(beanName, singletonObject);
}
}
4-1 添加单例
addSingleton(beanName, singletonObject)
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
3 DefaultListableBeanFactory
3-1 手动更新单例名称
updateManualSingletonNames(set -> set.add(beanName), set -> !this.beanDefinitionMap.containsKey(beanName))
private void updateManualSingletonNames(Consumer<Set<String>> action, Predicate<Set<String>> condition) {
// 如果已开始创建 Bean
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
if (condition.test(this.manualSingletonNames)) {
Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
action.accept(updatedSingletons);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// Still in startup registration phase
if (condition.test(this.manualSingletonNames)) {
action.accept(this.manualSingletonNames);
}
}
}
3-2 判断是否已开始创建 Bean
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
protected boolean hasBeanCreationStarted() {
return !this.alreadyCreated.isEmpty();
}
3-1 按类型清除缓存
clearByTypeCache()
private void clearByTypeCache() {
this.allBeanNamesByType.clear();
this.singletonBeanNamesByType.clear();
}
Spring源码 12 IOC refresh方法7的更多相关文章
- Spring源码 17 IOC refresh方法12
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 18 IOC refresh方法13
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 16 IOC refresh方法11
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 15 IOC refresh方法10
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 11 IOC refresh方法6
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 07 IOC refresh方法2
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 06 IOC refresh方法1
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 14 IOC refresh方法9
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- Spring源码 09 IOC refresh方法4
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
随机推荐
- 记一次IIS网站启动不了的问题排查
今天清理了下机器中的IIS网站,将很久不用的网站都删除. 因为需要删除的比较多,正在使用的很少,就将网站全部删除了,然后准备重新添加需要用的. 在添加了网站后,点击启动按钮,发现网站启动不了,因为网站 ...
- 这篇 DNS ,写的挺水的。
试想一个问题,我们人类可以有多少种识别自己的方式?可以通过身份证来识别,可以通过社保卡号来识别,也可以通过驾驶证来识别,尽管有多种识别方式,但在特定的环境下,某种识别方法会比其他方法更为适合.因特网上 ...
- Spring Boot整合Swagger报错:"this.condition" is null
前段时间看到群里有吐槽swagger整合问题,当时没仔细看,总以为是姿势不对. 这两天正好自己升级Spring Boot版本,然后突然出现了这样的一个错误: Caused by: java.lang. ...
- CF1601F Two Sorts
CF1601F Two Sorts 给定 \(n\),将 \(1\sim n\) 按照字典序排序,\(a_i\) 表示第 \(i\) 小的数,求: \[\left(\sum_{i=1}^{n} ((i ...
- 两个月吃透阿里P9推荐260页SpringBoot2企业应用实战pdf入职定P6+
前言 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置 ...
- Java开发学习(二)----IOC、DI入门案例
一.IOC入门案例 1.1 思路分析 (1)Spring是使用容器来管理bean对象的,那么管什么? 主要管理项目中所使用到的类对象,比如(Service和Dao) (2)如何将被管理的对象告知IOC ...
- python中collections.OrderedDict()
import collections #from collections import OrderededDict my_orderDict=collections.OrderedDict(house ...
- 轻量级多级菜单控制框架程序(C语言)
1.前言 作为嵌入式软件开发,可能经常会使用命令行或者显示屏等设备实现人机交互的功能,功能中通常情况都包含 UI 菜单设计:很多开发人员都会有自己的菜单框架模块,防止重复造轮子,网上有很多这种菜单框架 ...
- 怎么理解相互独立事件?真的是没有任何关系的事件吗?《考研概率论学习之我见》 -by zobol
1.从条件概率的定义来看独立事件的定义 2.从古典概率的定义来看独立事件的定义 3.P(A|B)和P(A)的关系是什么? 4.由P(AB)=P(A)P(B)推出"独立" 5.从韦恩 ...
- SAP Column tree
code as bellow *&---------------------------------------------------------------------* *& I ...