博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring源码 12 IOC refresh方法7
阅读量:37194 次
发布时间:2020-08-01

本文共 4785 字,大约阅读时间需要 15 分钟。

本文章基于 Spring 5.3.15

Spring IOC 的核心是 AbstractApplicationContextrefresh 方法。

其中一共有 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
> action, Predicate
> condition) { // 如果已开始创建 Bean if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { if (condition.test(this.manualSingletonNames)) { Set
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
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();}

转载地址:http://hupwwy.baihongyu.com/

你可能感兴趣的文章
seaborn绘图入门1(lineplot+barplot+heatmap+scatterplot)
查看>>
seaborn绘图入门2(distplot+kdeplot+jointplot+set_style)
查看>>
LeetCode 438. 找到字符串中所有字母异位词(滑动窗口)
查看>>
LeetCode 467. 环绕字符串中唯一的子字符串(思维转换)
查看>>
LeetCode 457. 环形数组循环(暴力+快慢指针)
查看>>
LeetCode 435. 无重叠区间(贪心/动态规划)
查看>>
LeetCode 433. 最小基因变化(广度优先搜索)
查看>>
LeetCode 436. 寻找右区间(二分查找)
查看>>
LeetCode 491. 递增子序列(回溯+判重剪枝)
查看>>
LeetCode 525. 连续数组(前缀和+哈希)
查看>>
LeetCode 516. 最长回文子序列(动态规划)
查看>>
Pandas入门1(DataFrame+Series读写/Index+Select+Assign)
查看>>
LeetCode 第 26 场双周赛(363/1971,前18.4%)
查看>>
LeetCode 1450. 在既定时间做作业的学生人数
查看>>
LeetCode 1451. 重新排列句子中的单词(桶排序)
查看>>
LeetCode 1452. 收藏清单(std::includes判断子集)
查看>>
LeetCode 1453. 圆形靶内的最大飞镖数量(几何题)
查看>>
Pandas入门2(DataFunctions+Maps+groupby+sort_values)
查看>>
LeetCode 372. 超级次方(快速幂)
查看>>
LeetCode 393. UTF-8 编码验证(位运算)
查看>>