Spring 源码分析 - bean的加载_虾王之王的技术博客_51CTO博客 文章中,我们介绍了Spring对 获取bean的过程,但是并没有详细解释 Bean 是如何创建的,本文就来分析Spring是如何创建的bean。阅读本文前,建议先阅读衍生篇,方便更好理解,本文有很多涉及到 BeanPostProcesser 的部分。

我们知道

DefaultSingletonBeanRegistry#getSingleton(java.lang.String, ObjectFactory<?>)这一步创建了bean,如下图:

Spring源码分析 - bean的获取_源码解析

到了这一步,Spring 就基本对 Bean已经创建好了 不抱什么希望了,所以着手开始自己创建bean。

本文就来分析 getSingleton(String beanName, ObjectFactory<?> singletonFactory) 方法整个流程。

二、获取单例 - getSingleton

如下, 是整个 getSingleton方法的代码,做了一些基本注释

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
  Assert.notNull(beanName, "Bean name must not be null");
  // 因为创建过程中需要操作 singletonObjects。所以需要加锁
  synchronized (this.singletonObjects) {
  	// 1. 再次尝试获取bean,判断bean是否已经加载。如果加载直接返回。
  	Object singletonObject = this.singletonObjects.get(beanName);
  	if (singletonObject == null) {
    // 2. 判断,如果当前beanFactory正在被销毁则直接抛出异常,不允许创建单例bean
    if (this.singletonsCurrentlyInDestruction) {
    	throw new BeanCreationNotAllowedException(beanName,
      	"Singleton bean creation not allowed while singletons of this factory are in destruction " +
      	"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
    }
    if (logger.isDebugEnabled()) {
    	logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
    }
    // 3. 做一些bean创建前的准备工作: 记录beanName 正在加载的状态(添加到 singletonsCurrentlyInCreation 缓存中),若bean已经正在加载,则抛出异常。为了解决循环引用的问题
    beforeSingletonCreation(beanName);
    boolean newSingleton = false;
    boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
    if (recordSuppressedExceptions) {
    	this.suppressedExceptions = new LinkedHashSet<>();
    }
    try {
    	// 4. 通过回调方式获取bean实例。
    	singletonObject = singletonFactory.getObject();
    	newSingleton = true;
    }
    catch (IllegalStateException ex) {
    	// Has the singleton object implicitly appeared in the meantime ->
    	// if yes, proceed with it since the exception indicates that state.
    	singletonObject = this.singletonObjects.get(beanName);
    	if (singletonObject == null) {
      throw ex;
    	}
    }
    catch (BeanCreationException ex) {
    	if (recordSuppressedExceptions) {
      for (Exception suppressedException : this.suppressedExceptions) {
      	ex.addRelatedCause(suppressedException);
      }
    	}
    	throw ex;
    }
    finally {
    	if (recordSuppressedExceptions) {
      this.suppressedExceptions = null;
    	}
    	// 5. 加载单例后的处理方法调用 : 删除bean正在创建的记录(从 singletonsCurrentlyInCreation  中移除 beanName)
    	afterSingletonCreation(beanName);
    }
    if (newSingleton) {
    	// 6. 加入到缓存中,并删除加载bean过程中所记录的各种辅助状态
    	addSingleton(beanName, singletonObject);
    }
  	}
  	return singletonObject;
  }
	}

	...
	// 主要还是对几个缓存map的操作
	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);
  }
	}
	...
	// 不包含 && 添加失败 :则认为Bean正在创建中,抛出异常
	protected void beforeSingletonCreation(String beanName) {
  if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
  	throw new BeanCurrentlyInCreationException(beanName);
  }
	}
	...
	// 不包含 && 移除失败 :认为Bean 已经创建结束,抛出异常。
	protected void afterSingletonCreation(String beanName) {
  if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
  	throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
  }
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.

上面的代码注释也比较清楚,基本流程如下:

this.singletonObjects.get(beanName); :再次尝试从缓存中获取bean,若获取到,则直接返回。

if (this.singletonsCurrentlyInDestruction) :未获取到检测bena是否正在销毁,若是则抛出异常

Spring源码分析 - bean的获取_Spring_02

beforeSingletonCreation 方法中记录bean正在创建的状态将beanName添加到singletonsCurrentlyInCreation集合中)。在循环依赖时可根据此判断。

singletonObject = singletonFactory.getObject(); :调用 ObjectFactory.getObject() 方法来实例化bean

afterSingletonCreation 方法移除bean正在夹杂的状态

addSingleton(beanName, singletonObject); : 对各种缓存状态做处理。

流程图如下所示 :

Spring源码分析 - bean的获取_源码解析_03

下面的流程图关于 beforeSingletonCreation 和 afterSingletonCreation 的注释写的有些问题,正确的描述如下:

inCreationCheckExclusions 不包含 beanName && singletonsCurrentlyInCreation 添加失败 :则认为Bean正在创建中,抛出异常

inCreationCheckExclusions 不包含 beanName && singletonsCurrentlyInCreation 移除失败 :认为Bean 已经创建结束,抛出异常。

可以非常直观的看出, getSingleton 方法中的关键逻辑非常简单,bean创建的具体逻辑在 singletonObject = singletonFactory.getObject(); 中,所以下面继续去分析singletonFactory.getObject()中做了什么。

三、创建bean - createBean概述

上面可以看到,主要步骤还是在回调的 getObject() 方法中。那么我们来看看在bean加载过程中的FactoryBean做了什么。代码如下:

Spring源码分析 - bean的获取_源码解析_04

兜了一大圈关键代码还是在createBean 方法里。接下来,我们就来仔细分析一下 createBean 方法。

AbstractAutowireCapableBeanFactory#createBean 方法代码如下 ,附带部分注释:

@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  	throws BeanCreationException {


  RootBeanDefinition mbdToUse = mbd;


  // 1. 锁定class, 根据mdb和 beanName 解析出来 class
  Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
  	mbdToUse = new RootBeanDefinition(mbd);
  	mbdToUse.setBeanClass(resolvedClass);
  }

  // Prepare method overrides.
  try {
  	// 2. 验证及准备覆盖的方法
  	mbdToUse.prepareMethodOverrides();
  }
  catch (BeanDefinitionValidationException ex) {
  	throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
    	beanName, "Validation of method overrides failed", ex);
  }

  try {
  	// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  	// 3. 调用BeanProcessors的方法来替代真正的实例
  	Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  	// 如果后处理器真的实现了,则直接返回使用后处理器的bean
  	if (bean != null) {
    return bean;
  	}
  }
  catch (Throwable ex) {
  	throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
    	"BeanPostProcessor before instantiation of bean failed", ex);
  }

  try {
  	// 4.  创建bean 的 真正方法
  	Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  	if (logger.isTraceEnabled()) {
    logger.trace("Finished creating instance of bean '" + beanName + "'");
  	}
  	return beanInstance;
  }
  catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
  	throw ex;
  }
  catch (Throwable ex) {
  	throw new BeanCreationException(
    	mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
  }
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.

可以看到,createBean 的整体流程大致如下:

根据设置的class属性或者根据className来解析Class。

对override 属性进行标记及验证。

应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作。

创建bean。

返回bean

流程图如下:

Spring源码分析 - bean的获取_Spring_05

四、创建bean - createBean详解

上面的逻辑看着似乎不复杂,实际上,真正的逻辑都被封装在了方法中,所以下面需要关注如下的几个方法:

1、resolveBeanClass

这里不再过多展示代码,这个方法的作用就是根据参数和返回值都能知道: 根据 BeanDefinition和 beanName 解析出 bean 的Class。

Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  • 1.

2、prepareMethodOverrides

见名知意: 准备方法重写,这里更多是做一个校验的功能。这个方法主要是针对 lookup-method 和 replaced-method 两个属性的,用来覆盖指定的方法。

mbdToUse.prepareMethodOverrides();
  • 1.

详细代码如下:

public void prepareMethodOverrides() throws BeanDefinitionValidationException {
  // Check that lookup methods exist and determine their overloaded status.
  // 判断是否有方法需要重写
  if (hasMethodOverrides()) {
  	getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
  }
	}

	protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
  // 获取对应的类中的对应方法名的个数
  int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
  // 等于0抛出异常。上面已经验证有方法需要覆盖,这里为0肯定错误
  if (count == 0) {
  	throw new BeanDefinitionValidationException(
    	"Invalid method override: no method with name '" + mo.getMethodName() +
    	"' on class [" + getBeanClassName() + "]");
  }
  else if (count == 1) {
  	// Mark override as not overloaded, to avoid the overhead of arg type checking.
  	// 标记 MethodOverride 暂未被覆盖,避免参数类型检查的开销。
  	mo.setOverloaded(false);
  }
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

解释一下上面的逻辑:

首先会判断是否有方法需要重写,这里的是根据 RootBeanDefinition 中的 methodOverrides 属性来进行判断,为空则表示没有。

若上述判断有方法需要覆盖,则会调用prepareMethodOverride(MethodOverride mo) 方法。而在 prepareMethodOverride(MethodOverride mo) 方法中会根据 需要覆盖的方法名称 来获取加载类中关于该方法的实现。如果获取不到 count == 0,则直接抛出异常,如果获取到只有一个 count == 1,则记录该方法并未被重载(因为Spring在方法匹配时,如果一个类中存在若干个重载方法,则在函数调用及增强的时候需要根据参数类型进行匹配,来最终确定调用的方法是哪一个,这里直接设置了该方法并未被重载,在后续方法匹配的时候就不需要进行参数匹配验证,直接调用即可)。

打个比方,比如指定覆盖A类中的 a方法,但是A类中可能存在多个a方法或者不存在a方法,若count == 0不 存在a方法,则谈何覆盖,直接抛出异常,若count ==1 则a方法的实现只有一个,标记该方法并未被重载后续可跳过参数验证的步骤。

3、resolveBeforeInstantiation

该方法主要是调用 InstantiationAwareBeanPostProcessor 来进行一些处理,这里实际上是给了用户一次代替Spring来创建bean的机会,代码实现上非常简单直接调用的后处理器方法。

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
	// 如果通过后置处理器创建出来bean,则直接返回创建的bean
	if (bean != null) {
  return bean;
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

该方法调用了后处理器的方法:

InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation : 在bean初始化前调用

BeanPostProcessor#postProcessAfterInitialization : 在bean初始化后调用

关于后处理器部分具体介绍请看衍生篇 :Spring 源码分析衍生篇四 : 后处理器 BeanPostProcesser

详细代码如下:在调用 doCreate 方法创建bean的实例前调用了该方法对 BeanDefinition 中的属性做一些前置处理。

@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  Object bean = null;
  // 如果尚未被解析
  if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
  	// Make sure bean class is actually resolved at this point.
  	// 当前类并非合成类 && 存在 BeanPostProcessor (后处理器)
  	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    // 1. 获取目标类
    Class<?> targetType = determineTargetType(beanName, mbd);
    if (targetType != null) {
    	// 2. 实例前的后处理器应用
    	bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    	if (bean != null) {
      // 3. 实例后的后处理器应用
      bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    	}
    }
  	}
  	mbd.beforeInstantiationResolved = (bean != null);
  }
  return bean;
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.

其中 applyBeanPostProcessorsBeforeInstantiation 和 applyBeanPostProcessorsAfterInitialization 很明显就是调用bean的后处理器,也就是对后处理器中的 InstantiationAwareBeanPostProcessor 类型的后处理器进行 postProcessBeforeInstantiation 方法 和 BeanPostProcessor 类型的 postProcessAfterInitialization 方法的调用。

3.1 determineTargetType(beanName, mbd);

关于 factoryMethodName 值的由来 这一点我们在 Spring 源码分析衍生篇七 :ConfigurationClassPostProcessor 上篇 中有过强调。即如果通过@Bean 注入,则保存期工厂类的方法名称,简单来说就是配置类中对应该bean的注入方法名称。

@Nullable
	protected Class<?> determineTargetType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
  // 获取目标类。这里获取的目标类并不一定是真正生成的类,可能是其真正类的父类或者父接口
  Class<?> targetType = mbd.getTargetType();
  if (targetType == null) {
  	// 根据mdb 是否存在 factoryMethodName 来确定是直接解析class还是通过 工厂类的方法返回值来获取class
  	targetType = (mbd.getFactoryMethodName() != null ?
    	getTypeForFactoryMethod(beanName, mbd, typesToMatch) :
    	resolveBeanClass(mbd, beanName, typesToMatch));
  	if (ObjectUtils.isEmpty(typesToMatch) || getTempClassLoader() == null) {
    mbd.resolvedTargetType = targetType;
  	}
  }
  return targetType;
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

需要注意的是 这里获取的 targetType 类型并不一定是真正生成的bean类型,也可能是实际类型 的父类或者父接口 。因为对于通过 @Bean 注解修饰注入到Spring容器的时候,BeanDefinition 的 factoryMethodName 属性值不为空,指向其工厂类的方法名。并且由于多态的特性,其工厂方法引入的类型并不一定是实际类型。这个类型的错误会在 AbstractAutowireCapableBeanFactory#doCreateBean 中纠正过来.

比如 :下面的 demoService()方法实际生成的类型是 DemoServiceImpl。这里返回的类型是DemoService 。那么我们这里获取到的 targetType 就是 DemoService.class。其 BeanDefinition.factoryMethodName = demoService (即 DemoConfig 生成DemoService的方法的名称)

public class DemoConfig {
    @Bean
    public DemoService demoService() {
        return new DemoServiceImpl();
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

3.2 postProcessBeforeInstantiation

在bean 实例化前调用,也就是将 AbstractBeanDefinition 转换为 BeanWrapper 前的处理。给子类一个修改BeanDefinition的机会,也就是说当程序经过这个方法后,bean可能已经不是我们所认为的bean了。或许是一个经过代理的代理bean。可能是通过cglib生成的,也可能是通过其他技术生成的。

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
  // 获取所有 BeanPostProcessor 进行遍历
  for (BeanPostProcessor bp : getBeanPostProcessors()) {
  	if (bp instanceof InstantiationAwareBeanPostProcessor) {
    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;    
    // 调用 postProcessBeforeInstantiation 方法
    Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
    if (result != null) {
    	return result;
    }
  	}
  }
  return null;
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

3.3 postProcessAfterInitialization

这里是bean创建后的后置方法调用,逻辑基本类似。不同的是到达这一步时,Bean已经创建成功,并且注入属性也进行了赋值。

需要注意,如果bean交由Spring来创建,那么Spring会将需要的属性注入到bean中,如果是自己代理生成(比如 通过 postProcessBeforeInstantiation 方法生成),那么需要自己解决bean的属性注入问题。

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
  	throws BeansException {

  Object result = existingBean;
  for (BeanPostProcessor processor : getBeanPostProcessors()) {
  	Object current = processor.postProcessAfterInitialization(result, beanName);
  	if (current == null) {
    return result;
  	}
  	result = current;
  }
  return result;
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

4、创建bean - doCreateBean

代码执行到这里,可以确定第三步中并没有返回一个非空的bean(BeanPostProcessor 并没有代理生成一个bean)。所以Spring开始自己着手创建bean。do开头的方法才是真正做事情的,所以这里才是真正创建bean的地方。

Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  • 1.

doCreateBean 代码如下,带有详细注释:

// 保存的是 FactoryBean 的beanName -> FactoryBean 的 BeanWrapper
	private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>();

	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
  	throws BeanCreationException {

  // Instantiate the bean.
  BeanWrapper instanceWrapper = null;
  if (mbd.isSingleton()) {
  	// 单例情况下清除缓存。这里保存的是 FactoryBean 和 BeanWrapper 的映射关系。 
  	// factoryBeanInstanceCache 是在创建其他bean的时候缓存了一下 FactoryBean 。至于单例模式下移除而不是获取,因为单例只需要创建一次 ? 尚未理解。
  	instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  }
  // 如果没有缓存,则重新创建
  if (instanceWrapper == null) {
  	// 1. 根据指定的bean使用对应的策略创建新的实例。如:工厂方法、构造函数自动注入,简单初始化
  	instanceWrapper = createBeanInstance(beanName, mbd, args);
  }
  // 获取bean实例
  final Object bean = instanceWrapper.getWrappedInstance();
  // 获取bean类型
  Class<?> beanType = instanceWrapper.getWrappedClass();
  // 将目标类型替换成实际生成的类型.纠正了上面说到类型错误(如果存在)
  if (beanType != NullBean.class) {
  	mbd.resolvedTargetType = beanType;
  }

  // Allow post-processors to modify the merged bean definition.
  // 2. 调用  MergedBeanDefinitionPostProcessor 后处理器
  synchronized (mbd.postProcessingLock) {
  	if (!mbd.postProcessed) {
    try {
    	// 调用  MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 后处理器的方法。
    	applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    }
    catch (Throwable ex) {
    	throw new BeanCreationException(mbd.getResourceDescription(), beanName,
      	"Post-processing of merged bean definition failed", ex);
    }
    mbd.postProcessed = true;
  	}
  }

  // Eagerly cache singletons to be able to resolve circular references
  // even when triggered by lifecycle interfaces like BeanFactoryAware.
  // 3. 判断是否需要提早曝光 : 单例 & 允许循环依赖 & 当前bean已经正在创建中
  // 由于当前bean已经在创建中,本次创建必然是循环引用造成的,所以这里判断是否可以需要提前曝光
  boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    isSingletonCurrentlyInCreation(beanName));
  if (earlySingletonExposure) {
  	if (logger.isTraceEnabled()) {
    logger.trace("Eagerly caching bean '" + beanName +
      "' to allow for resolving potential circular references");
  	}
  	// 4. 为避免后期循环依赖,在bean初始化完成前将创建实例的ObjectFactory 加入工程  -- 解决循环依赖
  	addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  }

  // Initialize the bean instance.
  Object exposedObject = bean;
  try {
  	//  5. 对bean进行属性填充,将各个属性值注入,其中如果存在依赖于其他bean的属性,则会递归初始依赖bean
  	populateBean(beanName, mbd, instanceWrapper);
  	// 调用初始化方法,比如 init-method
  	exposedObject = initializeBean(beanName, exposedObject, mbd);
  }
  catch (Throwable ex) {
  	if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
    throw (BeanCreationException) ex;
  	}
  	else {
    throw new BeanCreationException(
      mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
  	}
  }
  // 6. 进行循环依赖检查
  if (earlySingletonExposure) {
  	Object earlySingletonReference = getSingleton(beanName, false);
  	// earlySingletonReference  只有在检测到有循环依赖的情况下才会不为空
  	if (earlySingletonReference != null) {
  	// 如果 exposedObject没有在初始化方法中被改变,也就是没有被增强
    if (exposedObject == bean) {
    	exposedObject = earlySingletonReference;
    }
    else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
    	String[] dependentBeans = getDependentBeans(beanName);
    	Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
    	for (String dependentBean : dependentBeans) {
      // 检测依赖
      if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
      	actualDependentBeans.add(dependentBean);
      }
    	}
    	// 因为bean创建后其所依赖的bean一定是已经创建了的。actualDependentBeans不为空说明当前 bean创建后其依赖的bena却没有全部创建完,也就说说存在循环依赖。
    	if (!actualDependentBeans.isEmpty()) {
      throw new BeanCurrentlyInCreationException(beanName,
        "Bean with name '" + beanName + "' has been injected into other beans [" +
        StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
        "] in its raw version as part of a circular reference, but has eventually been " +
        "wrapped. This means that said other beans do not use the final version of the " +
        "bean. This is often the result of over-eager type matching - consider using " +
        "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
    	}
    }
  	}
  }

  // Register bean as disposable.
  try {
  	// 7.根据Scopse 注册bean
  	registerDisposableBeanIfNecessary(beanName, bean, mbd);
  }
  catch (BeanDefinitionValidationException ex) {
  	throw new BeanCreationException(
    	mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  }

  return exposedObject;
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.

可以看到大致逻辑如下:

createBeanInstance(beanName, mbd, args) :实例化bean,将BeanDefinition转换为BeanWrapper

applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); : MergedBeanDefinitionPostProcessor 后处理器的应用。bean合并后的处理,比如 @Autowired、@Value注解正是通过 AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition 此方法实现的预解析。

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); : 关于循环依赖的处理,添加 ObjectFactory到singletonFactories缓存中,同时这里给了用户一个机会通过调用 SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference 方法来由用户生成暴露的实例

populateBean(beanName, mbd, instanceWrapper); :对创建的bean内部的一些属性进行填充注入

initializeBean(beanName, exposedObject, mbd); : 初始化bean的一些属性,如Aware 接口的实现, init-method属性等

循环依赖检查。和第四步不同的是,这里了是判断是否无法解决循环依赖,否则抛出异常。

registerDisposableBeanIfNecessary(beanName, bean, mbd); : 注册DisposableBean

完成创建并返回。

doCreatebean 方法的代码量非常大,这里由于篇幅问题,需要新开篇分析,所以本文中挑选几个简单的方法分析,复杂的方法新开篇分析。

4.1 createBeanInstance

见名知意 : 该方法完成了bean的实例创建。

instanceWrapper= createBeanInstance(beanName, mbd, args);
  • 1.

大概逻辑可以概括为:

如果存在工厂方法则使用工厂方法进行初始化

若类有多个构造函数,则根据参数锁定构造函数并初始化

如果即不存在工厂方法也不存在带参构造函数,则使用默认的构造函数进行bean的实例化。

具体的代码分析已成文 : Spring源码分析六:bean的创建④ - createBeanInstance

4.2 applyMergedBeanDefinitionPostProcessors

这种方法命名的也见得多了,见名知意: 该方法完成了 MergedBeanDefinitionPostProcessors 后处理器的功能。主要是 bean合并后的处理。在 AutowiredAnnotationBeanPostProcessor对postProcessMergedBeanDefinition方法的实现中,就对@Autowired、@Value 等注解进行了一系列的预处理,这里我们并不需要太过在意。

关于 AutowiredAnnotationBeanPostProcessor 的内容详参衍生篇 : Spring源码分析衍生篇五 :AutowiredAnnotationBeanPostProcessor

applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
  • 1.

详细代码如下,不再具体分析

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
  for (BeanPostProcessor bp : getBeanPostProcessors()) {
  	if (bp instanceof MergedBeanDefinitionPostProcessor) {
    MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
    bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
  	}
  }
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

4.3 addSingletonFactory

这一部分的逻辑就是为了解决循环依赖的问题,将未创建完成的当前bean,通过ObjectFactory进行一个包装,提前暴露给其他bean。

我们实际的分析是一部分代码块如下:

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    isSingletonCurrentlyInCreation(beanName));
  if (earlySingletonExposure) {
  	if (logger.isTraceEnabled()) {
    logger.trace("Eagerly caching bean '" + beanName +
      "' to allow for resolving potential circular references");
  	}
  	// 这里为了避免后期的循环依赖,在bean初始化前将创建实例的ObjectFactory加入工厂中。
  	addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

首先我们需要分析出 earlySingletonExposure 为true的条件:

bean是单例

允许循环依赖

当前bean正在创建中 : singletonsCurrentlyInCreation 包含当前bean。在Spring 中 有专门的属性记录 bean的加载状态 – DefaultSingletonBeanRegistry#singletonsCurrentlyInCreation。在bean创建前会将bean添加,bean创建结束后将bean移除。这一点我们在前篇有过提及。

满足上述三个条件后,则会 调用 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); 方法。这个方法作用是将正在创建的bean缓存起来,主要目的还是用来解决循环依赖的问题。

循环依赖相关内容请阅: Spring 源码分析衍生篇二 : Spring中的循环依赖

详细代码如下:

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    isSingletonCurrentlyInCreation(beanName));
  if (earlySingletonExposure) {
  	if (logger.isTraceEnabled()) {
    logger.trace("Eagerly caching bean '" + beanName +
      "' to allow for resolving potential circular references");
  	}
  	// 这里为了避免后期的循环依赖,在bean初始化前将创建实例的ObjectFactory加入工厂中。
  	addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  }
  
	...
	// 对一系列缓存map 做处理。在 singletonFactories 中保存 ObjectFactory 类型,进行提前暴露
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
  Assert.notNull(singletonFactory, "Singleton factory must not be null");
  synchronized (this.singletonObjects) {
  	// 如果singletonObjects不存在(bean未创建成功)
  	if (!this.singletonObjects.containsKey(beanName)) {
    this.singletonFactories.put(beanName, singletonFactory);
    this.earlySingletonObjects.remove(beanName);
    this.registeredSingletons.add(beanName);
  	}
  }
	}
	
	...
	// 给调用者一次机会,主要就是调用了SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference 方法。将getEarlyBeanReference  方法的返回值作为提前暴露的对象。
	// 我们可以通过实现 getEarlyBeanReference  方法来替代Spring提前暴露的对象
	// Aop 就是在这里将 Advice 动态织入bean中,若没有bean则直接返回bean,不做任何处理
	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
  Object exposedObject = bean;
  if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  	for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
    	SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
    	exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
    }
  	}
  }
  return exposedObject;
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.

该方法中 getEarlyBeanReference 调用了后处理器的方法,可用于用户自己扩展替换Spring生成的提前暴露的对象 :

SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference (Object bean, String beanName);

4.4 populateBean

见名知意,下面这个方法是用来属性注入的。

populateBean 方法则是对bean 属性的注入,上面的 createBeanInstance 方法创建了 bean,但是其内部属性并没有注入,比如通过 @Autowired 注解注入的变量属性,此时还为null,需要对这种属性进行注入,这一步就是完成这种功能。

populateBean(beanName, mbd, instanceWrapper);
  • 1.

在这里方法里按照如下顺序调用了后处理器

InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation : 返回true 才会调用下面两个方法

InstantiationAwareBeanPostProcessor.postProcessProperties : 进行属性的注入。

InstantiationAwareBeanPostProcessor.postProcessPropertyValues : 已过时

篇幅所限,详细的代码分析请阅 Spring源码分析七:bean的属性注入⑤ - populateBean

4.5 initializeBean

到达这一步,其实bean已经创建结束了,这一步是完成最后的功能,提供一些功能的实现,如Aware 接口的实现, init-method、InitializingBean属性等。

exposedObject= initializeBean(beanName, exposedObject, mbd);
  • 1.

篇幅所限,详情请阅 : Spring源码分析八:bean的初始化⑥ - initializeBean

4.6 循环依赖检查

Spring 循环依赖的解决仅对单例且非构造函数构造的形式有效,对于原型模式的bean,Spring直接抛出异常,在这个步骤中会检测已经加载的bean 是否已经出现了循环依赖,并判断是否需要抛出异常。

// earlySingletonExposure 为true 说明要校验循环依赖的问题
	if (earlySingletonExposure) {
  // 调用了 getSingleton 方法获取缓存中的对象,这里注意传递的false。
  Object earlySingletonReference = getSingleton(beanName, false);
  // 如果 earlySingletonReference  不为空,则说明存在循环依赖
  if (earlySingletonReference != null) {
  	// 如果缓存的对象 exposedObject == bean,直接赋值之前暴露出来的bean
  	// 这里
  	if (exposedObject == bean) {
    exposedObject = earlySingletonReference;
  	}
  	// allowRawInjectionDespiteWrapping 默认false && beanName 被其他bean依赖
  	else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
    // 获取依赖于 当前bean的 beanName
    String[] dependentBeans = getDependentBeans(beanName);
    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
    for (String dependentBean : dependentBeans) {
    	// 
    	if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
      actualDependentBeans.add(dependentBean);
    	}
    }
    // 如果 actualDependentBeans 不为空,则抛出循环依赖的异常
    if (!actualDependentBeans.isEmpty()) {
    	throw new BeanCurrentlyInCreationException(beanName,
      	"Bean with name '" + beanName + "' has been injected into other beans [" +
      	StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
      	"] in its raw version as part of a circular reference, but has eventually been " +
      	"wrapped. This means that said other beans do not use the final version of the " +
      	"bean. This is often the result of over-eager type matching - consider using " +
      	"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
    }
  	}
  }
	}

	...
	// 上面调用的 getSingleton 方法。可以知道这里传递的 allowEarlyReference 为false。
	// 因为当前bean在进行循环创建的时候,就已经将 bean缓存到 earlySingletonObjects 中了
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  Object singletonObject = this.singletonObjects.get(beanName);
  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
  	synchronized (this.singletonObjects) {
    singletonObject = this.earlySingletonObjects.get(beanName);
    if (singletonObject == null && allowEarlyReference) {
    	ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
    	if (singletonFactory != null) {
      singletonObject = singletonFactory.getObject();
      this.earlySingletonObjects.put(beanName, singletonObject);
      this.singletonFactories.remove(beanName);
    	}
    }
  	}
  }
  return singletonObject;
	}

	...
	// 删除给定bean名称的单例实例(如果有的话),但前提是该类型仅用于类型检查以外的用途。
	protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
  if (!this.alreadyCreated.contains(beanName)) {
  	removeSingleton(beanName);
  	return true;
  }
  else {
  	return false;
  }
	}

	...
	protected void removeSingleton(String beanName) {
  synchronized (getSingletonMutex()) {
  	super.removeSingleton(beanName);
  	this.factoryBeanObjectCache.remove(beanName);
  }
	}
	...
	// super.removeSingleton(beanName); 如下
	protected void removeSingleton(String beanName) {
  synchronized (this.singletonObjects) {
  	this.singletonObjects.remove(beanName);
  	this.singletonFactories.remove(beanName);
  	this.earlySingletonObjects.remove(beanName);
  	this.registeredSingletons.remove(beanName);
  }
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.

关于这一段的逻辑参考 : https://blog.youkuaiyun.com/qq_18297675/article/details/103674833

整个逻辑如下:

getSingleton(beanName, false); : 从缓存中获取缓存对象,这传递的false, 直接从 earlySingletonObjects 中获取循环依赖的对象 earlySingletonReference。

如果 earlySingletonReference == bean ,说明bean没有被修改,直接赋值即可。

如果 earlySingletonReference != bean ,那么说明 在 下面的代码中,bean被修改了

populateBean(beanName, mbd, instanceWrapper);
	exposedObject = initializeBean(beanName, exposedObject, mbd);
  • 1.
  • 2.

此时需获取依赖于当前bean的 dependentBeans。如果dependentBeans 中有已经创建好的,那么则抛出异常

4.7 registerDisposableBeanIfNecessary

这一步的目的是实现 destory-method 属性,如果bean配置了该属性,则需要注册以便在销毁时调用。

详细代码如下:

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
  AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
  if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
  	if (mbd.isSingleton()) {
    // Register a DisposableBean implementation that performs all destruction
    // work for the given bean: DestructionAwareBeanPostProcessors,
    // DisposableBean interface, custom destroy method.
    // 单例模式下注册需要销毁的bean,此方法会处理实现DisposableBean的bean
    // 并且对所有的bean使用 DestructionAwareBeanPostProcessor 处理 DisposableBean DestructionAwareBeanPostProcessor
    registerDisposableBean(beanName,
      new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
  	}
  	else {
    // A bean with a custom scope...
    // 自定义 scope 的处理
    Scope scope = this.scopes.get(mbd.getScope());
    if (scope == null) {
    	throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
    }
    scope.registerDestructionCallback(beanName,
      new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
  	}
  }
	}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.