我们前两篇文章介绍了Bean初始化的准备工作,这篇文章正式介绍Bean的加载过程,看看getBean()中都做了什么。

其实在之前有提到过,bean的加载并不是都在finishBeanFactoryInitialization方法中进行,而更早的在BFPP和BDRPP中就有看到显式的getBean方法的调用,所以我们这次换个入口,从invokeBeanFactoryPostProcessors中看getBean()。
invokeBeanFactoryPostProcessors
可以看到在invokeBeanFactoryPostProcessors方法中对getBean()的显式调用。
//省略部分源码
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
if (beanFactory instanceof BeanDefinitionRegistry) {
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
}
}
}
}
doGetBean
流程图

getBean()方法中直接对doGetBean()方法进行调用。
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//获取最终的beanName
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 主动检查手工注册的单例缓存。(尝试从singletonObject缓存中获取,解决循环依赖)
Object sharedInstance = getSingleton(beanName);
//如果单例缓存中不为null,则看该实例是否实现了FactoryBean,如果实现了则创建实例
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 判断scope = prototype的实例bean是否在创建中
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
//获取父类的beanFactory
//Spring中都是单一容器,SpringMVC中会存在父子容器
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果父工厂不为null,并且当前BeanFactory中不包含该bean
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 获取name对应的规范名称【全类名】,如果name前面有'&',则会返回'&'+规范名称【全类名】
String nameToLookup = originalBeanName(name);
//如果父工厂是AbstractBeanFactory,则调用父工厂doGetBean方法进行实例的创建
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
// 如果有创建bean实例时要使用的参数
//使用父工厂获取该bean对象, bean全类名和创建bean实例时要使用的参数
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
// 没有创建bean实例时要使用的参数 -> 委托给标准的getBean方法。
// 使用父工厂获取该bean对象,通bean全类名和所需的bean类型
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
// 使用父工厂获取bean,通过bean全类名
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
//根据传递的typeCheckOnly来进行判断,这里是false
if (!typeCheckOnly) {
//放入alreadyCreated缓存中,标记当前bean已经创建,
markBeanAsCreated(beanName);
}
try {
//将bean进行merge操作,返回merge后的RootBeanDefinition
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//如果当前bean是Abstract,抛出异常
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 如果存在依赖的bean的话,那么则优先实例化依赖的bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 如果存在依赖,则需要递归实例化依赖的bean
for (String dep : dependsOn) {
// 如果beanName已注册依赖于dependentBeanName的关系
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册各个bean的依赖关系,方便进行销毁
registerDependentBean(dep, beanName);
try {
// 递归优先实例化被依赖的Bean
getBean(dep);
}
}
}
// Create bean instance.
//bean的范围是 SINGLETON 或者 DEFAULT
//创建bean的实例对象
if (mbd.isSingleton()) {
//从缓存中获取实例bean
sharedInstance = getSingleton(beanName, () -> {
try {
//创建bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 如果 bean的范围是 PROTOTYPE
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
//如果是 PROTOTYPE,则创建一个新实例
Object prototypeInstance = null;
try {
//创建bean实例钱的准备工作,将beanName添加到ThreadLocal中,表示当前bean正在创建中
beforePrototypeCreation(beanName);
//创建实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//创建完实例后,将beanName从ThreadLocal中移除
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
//如果scopeName 为 null 则抛出异常。
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
//使用 ThreadLocal 作为缓存
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
//创建完实例后,将beanName从ThreadLocal中移除
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
}
}
}
return (T) bean;
}
getSingleton
首先尝试从一级缓存singletonObjects中获取对象。
/**
* 获取单例对象。
* 此方法用于在单例对象创建过程中或者创建后获取该对象。
* 如果对象还未完全创建,根据allowEarlyReference参数决定是否返回一个早期引用。
*
* @param beanName 要获取的Bean的名称。
* @param allowEarlyReference 如果为true,并且bean允许早期引用,那么在单例对象还没有完全创建时也可以返回这个对象的早期引用。
* @return 返回指定beanName的单例对象。如果没有找到对应的单例对象,且不允许早期引用,或者不允许早期访问,则返回null。
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 快速检查是否已有实例,无需完全锁定单例
Object singletonObject = this.singletonObjects.get(beanName);
// 如果singletonObject缓存中没有找到,&&
// singletonsCurrentlyInCreation中有(说明该bean正在创建中)
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//从早期单例对象缓存中获取,(之所称成为早期单例对象,是因为earlySingletonObjects里
// 的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作)
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果早期单例对象缓存也没有,并且允许创建早期单例对象引用
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 当某些方法需要提前初始化的时候则会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 如果存在单例工厂对象,则调用其getObject方法获取单例对象
singletonObject = singletonFactory.getObject();
// 存储获取到的singletonObject为早期引用,并移除对应的singletonFactory
this.earlySingletonObjects.put(beanName, singletonObject);
// 从三级缓存中移除
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
//返回singletonObject
return singletonObject;
}
上面源码中可以看到对当前Bean创建状态的判断。
protected void beforeSingletonCreation(String beanName) {
// 如果当前在创建检查中的排除bean名列表中不包含该beanName且将beanName添加到当前正在创建的bean名称列表后,出现
// beanName已经在当前正在创建的bean名称列表中添加过
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
作用在于:如果以时间维度来看,一个Bean的创建过程大致可以分为 新生状态 -》 开始创建 -》 … -》 完整对象。
如果我当前Bean尚未创建完成,此时想要直接获取实例对象,是不可以的,所以状态标志位可以用来判断当前Bean的创建状态。

源码中的这里有一个lamda表达式,并return了createBean(),那createBean()方法是在什么时候进行调用的呢? 是作为getSingleton方法的参数,在getSingleton之前么?
if (mbd.isSingleton()) {
//从缓存中获取实例bean
sharedInstance = getSingleton(beanName, () -> {
try {
//创建bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
可以看到getSingleton方法中有个参数为ObjectFactory> singletonFactory类型,而createBean方法的调用会在下面源码中执行singletonFactory.getObject();方法时,进行调用。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
// 快速检查是否已有实例
Object singletonObject = this.singletonObjects.get(beanName);
//如果缓存中没有
if (singletonObject == null) {
//标志位,标志当前bean是否正在销毁
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException;
}
// 创建单例之前的回调,默认实现将单例注册为当前正在创建中
beforeSingletonCreation(beanName);
//生成新的单例对象的标记, 当前为false 表示尚未生成新的单例对象
boolean newSingleton = false;
//suppressedExceptions标记 = null , 则实例化 suppressedExceptions
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 会调用 singletonFactory 中的方法创建单例对象,这里是 createBean() 方法
singletonObject = singletonFactory.getObject();
//生成新的单例对象后,改变标记为 true
newSingleton = true;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
ObjectFactory
源码中包含着@FunctionalInterface注解,说明是一个函数式编程,而函数式编程的调用,会在调用getObject()时,执行createBean方法。
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}