Spring源码阅读之初始化非懒加载bean实例-第1篇

>>强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!

在经历了前面BeanDefinition定义和BeanPostProcessor的准备工作完成之后,终于到了千呼万唤始出来的bean实例初始化了,也就是平时想用哪个类对应的实例直接从BeanFactory要的对象时怎么被创建出来的?由于这块逻辑比较复杂,还涉及到"循环依赖"等等一系列问题,所以我会在接下来利用两三篇文章来逐一说明。你们准备好一次搞定bean实例初始化的流程了吗?关于测试用例我们还是沿用UserService

说明一下,关于以下几个方法,不是我们关注的重点,暂时先不讨论,后面有时间我们在来介绍

  • initMessageSource():初始化国际化相关
  • initApplicationEventMulticaster():初始化事件分发器
  • onRefresh():初始化特殊的bean实例,无任何实现,预留出来的扩展点
  • registerListeners():注册监听器

  1. 关于BeanDefinition的几点提前说明
  • GenericBeanDefinition:配置为xml文件被解析为这个BeanDefinition定义
  • ScannedGenericBeanDefinition:由注解声明的被解析成这个BeanDefinition
  • 在bean实例化开始我们会遇到一个叫mergedBeanDefinition的bean定义,由于BeanDefinition会存在如下情况:
    1. BeanDefinition存在父BeanDefinition
    2. BeanDefinition不存在父BeanDefinition且本身是一个RootBeanDefinition
    3. BeanDefinition不是一个RootBeanDefinition,而是一个自定义的BeanDefinition

所以在bean实例化开始把这些情况统一命名为mergedBeanDefinition。


  1. 看看finishBeanFactoryInitialization()的具体实现。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// Step1:初始化当前上下文的转换器
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}

// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// Step2:如果BeanFactory没有内嵌值解析器,则添加一个默认的值解析器,这个解析器的作用是将注解里面配的类似 ${} 替换成真正的值
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}

// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// Step3:初始化LoadTimeWeaverAware bean实例
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}

// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);

// Allow for caching all bean definition metadata, not expecting further changes.
// Step4:冻结BeanDefinition定义,因为之后就是开始创建BeanDefinition对应的实例了
beanFactory.freezeConfiguration();

// Instantiate all remaining (non-lazy-init) singletons.
// Step5:重点,实例化所有剩余的非懒加载的单例Bean实例
beanFactory.preInstantiateSingletons();
}

  1. 来看下beanFactory.preInstantiateSingletons()的具体实现。
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}

// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

// Trigger initialization of all non-lazy singleton beans...
// Step1:遍历当前BeanFactory里面的所有beanName
for (String beanName : beanNames) {
// Step1.1:根据beanName获取对应的MergedBeanDefinition定义。
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// Step1.2:bd不是抽象的 && bd是单例的 && bd是非懒加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// Step1.2.1:根据当前beanName判断对应的bean实例是否是一个FactoryBean。
if (isFactoryBean(beanName)) {
// Step1.2.1.1:带上前缀获取FactoryBean
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// Step1.2.1.2:获取到的bean是一个FactoryBean
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
// Step1.2.1.3:需要提前加载,根据beanName获取对应的bean实例并将其注册到BeanFactory里面。
if (isEagerInit) {
getBean(beanName);
}
}
}
//1.2.2:非FactoryBean,则直接获取对应的bean实例并将其注册到BeanFactory里面。
else {
getBean(beanName);
}
}
}

// Trigger post-initialization callback for all applicable beans...
// Step2:遍历beanName获取对应的bean实例。
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
// Step2.1:如果当前实例实现了SmartInitializingSingleton,则可以调用其实现的afterSingletonsInstantiated方法,可以在这个方法中做一些事情。
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
// Step2.1.1:是否需要安全检测
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}

  1. 基于以上的实现,我们先来看看如果根据beanName获取到对应的MergedBeanDefinition定义的。
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// Step1:存MergedBeanDefinitions缓存获取对应的BeanDefinition定义,快速返回BeanDefinition定义,这种类似的缓存在Sprin后面的源码也会大量用到,我们在文末总结一下今天见到的本地缓存
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
// Step2:首先根据beanName获取到对应的BeanDefinition定义,然后在根据BeanDefinition和beanName获取到RootBeanDefinition。
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
// Step1:从beanDefinitionMap获取对应的BeanDefinition,这里存放的就是我们在 obtainFreshBeanFactory() 方法里面创建出来的BeanDefinition定义,理论上这里肯定可以获取得到对应的BeanDefinition,如果取不到就抛出异常。
BeanDefinition bd = this.beanDefinitionMap.get(beanName);

if (bd == null) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}

  1. 根据beanNameBeanDefinition获取对应的RootBeanDefinition定义
// 拿到了beanName和对应的BeanDefinition定义,我们来看看是怎么获取到对应的RootBeanDefinition定义的。
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)

throws BeanDefinitionStoreException
{

synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;

// Check with full lock now in order to enforce the same merged instance.
// Step1:从缓存中获取对应的RootBeanDefinition定义。
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
// Step2:本地缓存中不存在。
if (mbd == null) {
// Step2.1:判断当前BeanDefinition是否存在父BeanDefinition,如果不存在父BeanDefinition。
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
// Step2.1.1:实现了RootBeanDefinition接口,则拿BeanDefinition克隆一个RootBeanDefinition
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
// Step2.1.2:直接使用当前BeanDefinition创建一个对应的RootBeanDefinition定义。
mbd = new RootBeanDefinition(bd);
}
}
else {
// Child bean definition: needs to be merged with parent.
// Step2.2:存在父BeanDefinition,获取父BeanDefinition对应的名字
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
// Step2.3:判断当前BeanName和父BeanName不同,则根据父beanName获取父BeanDefinition定义
if (!beanName.equals(parentBeanName)) {
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
// Step2.4:获取父BeanFactory,如果父BeanFactory实现了ConfigurableBeanFactory接口,使用父BeanFactory获取父BeanDefinition
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
// Step2.3:使用父BeanDefinition创建一个RootBeanDefinition定义,然后将当前BeanDefinition(子BeanDefinition)的属性覆盖上去。
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}

// Set default singleton scope, if not configured before.
// Step2.4:设置scope属性,默认的都是单例的。
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}

// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
// Step2.5:对外部传进来的BeanDefinition设置scope属性。
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}

// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
// Step2.6:将创建出来的RootBeanDefinition定义回种到本地缓存里面。
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
// Step3:返回创建好的RootBeanDefinition定义。
return mbd;
}
}

  1. 获取当前BeanDefinition对应的父BeanDefinition对应的beanName
// 接着看看根据父beanName获取对应的名字
protected String transformedBeanName(String name) {
// BeanFactoryUtils.transformedBeanName这个操作就是将FactoryBean的前缀去掉。
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
// 从别名map里面获取对应的beanName,返回别名对应的真实beanName。
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}

  1. 拿到了父beanName,根据父beanName获取对应的BeanDefinition定义。
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
// Step1. 获取别名对应的真实beanName。
String beanName = transformedBeanName(name);

// Efficiently check whether bean definition exists in this factory.
// Step2:如果当前的BeanFactory不存在BeanDefinition定义 && 父BeanFactory实现了ConfigurableBeanFactory,则从父BeanFactory里面获取对应的RootBeanDefinition定义。
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
}
// Resolve merged bean definition locally.
// Step3:没取到,则新创建。
return getMergedLocalBeanDefinition(beanName);
}

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
// Step1:从mergedBeanDefinitions缓存优先获取,取到则直接返回。
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
// Step2:如果没有取到,则根据当前的beanName获取对应的beanDefinition定义,然后在递归调用getMergedBeanDefinition()方法获取对应的RootBeanDefinition定义。
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

  1. 以上内容稍微绕点,仔细看两遍应该也比较好懂,总结一下就是如果当前BeanDefinition存在父BeanDefinition,则先获取到父BeanDefinition,然后在将当前BeanDefinition的属性覆盖到父BeanDefinition上,然后创建对应的RootBeanDefinition返回。到此我们得到了RootBeanDefinition定义,接下来看看beanName对应的实例是否是FactoryBean
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
// Step1:获取真实的beanName
String beanName = transformedBeanName(name);
// Step2:获取beanName对应的bean实例
Object beanInstance = getSingleton(beanName, false);
// Step3:如果获取到了对应的bean实例,则直接判断其是否实现了FactoryBean接口,如果是则认为是FactoryBean。
if (beanInstance != null) {
return (beanInstance instanceof FactoryBean);
}

// No singleton instance found -> check bean definition.
// Step4:如果当前BeanFactory里面不存在对应的bean实例,则从父BeanFactory里面获取。
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
// Step5:当前BeanFactory存在,则选获取对应RootBeanDefinition定义,获取对应的beanType,根据beanType判断是否是一个FactoryBean。
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}

  1. 接着来看看getSingleton()是怎么获取beanName对应的bean实例的。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Step1:从singletonObjects缓存中获取对象
Object singletonObject = this.singletonObjects.get(beanName);
// Step2:如果从缓存中没取到 && beanName对应的bean实例正在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// Step2.1:从earlySingletonObjects缓存中获取对应的bean实例
singletonObject = this.earlySingletonObjects.get(beanName);
// Step2.2:从缓存中没有取到 && allowEarlyReference为true
if (singletonObject == null && allowEarlyReference) {
// Step2.2.1:从singletonFactories缓存中获取bean实例,如果能获取到,将bean实例回种到前两个缓存中,然后将bean实例返回。
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
// Step3:返回bean实例
return singletonObject;
}

  1. 再来看看isFactoryBean()是怎么预测beanType是否是FactoryBean的。
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
// Step1:根据beanName和RootBeanDefinition获取一个bean类型。
Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
// Step2:如果有对应的bean类型 && 如果bean类型是通过FactoryBean分配的,则认为是一个FactoryBean。isAssignableFrom调用的是一个native方法。
return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
}

总结

来总结一下本篇文章里面遇到的几个本地缓存。

  • beanDefinitionMap:存放BeanDefinition定义
  • mergedBeanDefinitions:存放RootBeanDefinition定义
  • singletonObjects:存放bean实例,相当于bean实例的一级缓存
  • earlySingletonObjects:存放bean实例,相当于bean实例的二级缓存
  • singletonFactories:存放bean实例对应的BeanFactory,通过BeanFactory创建相应的bean实例,相当于bean实例的三级缓存
  • singletonsCurrentlyInCreation:存放当前正在创建的bean实例

到此,我们遍历了每个beanName拿到了对应的RootBeanDefinition定义,然后判断了beanName对应的bean实例是否是一个FactoryBean。下一篇文章来分析根据beanName获取对应的bean实例。

Spring源码阅读之初始化非懒加载bean实例-第1篇

欢饮关注我,一起学习

原文始发于微信公众号(z小赵):Spring源码阅读之初始化非懒加载bean实例-第1篇