Spring 源码阅读笔记 (九) 主线 initMessageSource方法解读

497 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

Spring 源码阅读笔记(九)

前篇导航

Spring 源码阅读笔记(一)
Spring 源码阅读笔记(二)
Spring 源码阅读笔记(三)
Spring 源码阅读笔记(四)
Spring 源码阅读笔记(五)
Spring 源码阅读笔记(六) 主线 registerBeanPostProcessors解读
Spring 源码阅读笔记(七) 支线 getBean方法解读
Spring 源码阅读笔记(八) 支线createBean方法解读

前篇回顾

连续写了两篇支线,getBean和createBean方法,这两篇文章在Spring中还是很有用的,看完以后懂了很多知识点。

这篇将继续回归主线,先来看一下流程图。 image.png

在上一次主线任务中,讲到了registerBeanPostProcessors,到下一个方法是initMessageSource(),至于这个MessageSource是干嘛的,我也不知道,先来看一下代码吧

正式开始

initMessageSource

// Initialize message source for this context.
// 为此上下文初始化消息源。
initMessageSource();

protected void initMessageSource() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   // MESSAGE_SOURCE_BEAN_NAME = messageSource
   if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
       // ...
   }
   else {
       // ...
   }
}

先看一下大概的框架,其中的实现先不看,这里一进入方法,就看到一个If,由If区分了两条代码分支。

第一行代码获取了一下当前的Bean工厂,随后就判断了工厂中有无名叫messageSource的Bean对象。很明显,我们第一次进来,这里结果肯定为False,进入了else代码分支。

initMessageSource 的Else分支

// Use empty MessageSource to be able to accept getMessage calls.
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 + "]");
}

第一行的注释内容要翻译一下,看看对阅读代码有没有帮助。

Use empty MessageSource to be able to accept getMessage calls.
使用空MessageSource可以接受getMessage调用。

读完以后发现好像看不懂😂,直接读代码吧 一开始 new了一个DelegatingMessageSource对象,发现这个类是默认空参构造,没有什么特别的地方。

下一行代码调用了getInternalParentMessageSource,根据字面意思是过去内部的父级MessageSource这里要去看一下他的实现。

@Nullable
protected MessageSource getInternalParentMessageSource() {
   return (getParent() instanceof AbstractApplicationContext ?
         ((AbstractApplicationContext) getParent()).messageSource : getParent());
}

看了下,实现很简单,获取了当前applicationContext的上一级ApplicationContext,判断类型,看是否继承自AbstractApplicationContext,是的话就说明当前的Conetxt具备messageSource属性,可以直接获取。否则返回getParent方法,继续深入得只getParent方法返回ApplicationContext接口,ApplicationConetxt接口继承自MessageSource。

后面的代码向当前的ApplicationContext中加入了刚刚创建的MessageSource。

随后像Bean工厂中注册了名为messageSource的Bean。至于这里的registerSingleton方法,我们在上一篇文章,CreateBean方法的讲解中有见过这个方法,位于DefaultSingletonBeanRegistry中,向singletonObjects对象中put了Bean。

告一段落

这篇文章到这里就结束了,发现这个方法有点简单,只是创建了一个MessageSource对象,至于这个对象在后面有起到什么作用,我们后面拭目以待吧。

都看到这了,点个赞再走呗,宝~

结束语

写文章的目的是为了帮助自己巩固知识,写的不好或者错误的地方可以在评论区指出。如果您看了文章觉得对您有所帮助可以点个赞,如果发现有些问题产生了疑惑,或者不明白的可以评论、加我微信,一定知无不言。当然也希望和大家交个朋友,相互学习。