《Spring系列》第8章 Bean的加载(一) getBean()

前言

当获取Bean对象的时候,会通过BeanFactory接口提供的getBean()来获取,这个方法在子类AbstractBeanFactory得到了实现,

getBean是创建Bean的入口,具体实现需要doGetBean(),那么接下来就来看一下源码

doGetBean()

	// AbstractBeanFactory
	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
         // <1> 转换Bean名称,可能存在别名循环引用的问题
		String beanName = transformedBeanName(name);
		Object beanInstance;

		// Eagerly check singleton cache for manually registered singletons.
         // <2> 检查缓存中或者实例工厂是否有对应的实例
         // 如果是获取普通的bean则缓存中肯定获取不到,  但是如果获取的bean存在循环依赖, 那么缓存中就存在
         // Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光
         // 如果存在循环依赖, 那么缓存中存在, 存在的对象是2种情况: 1)未属性注入的普通bean 2)经过AOP的代理对象
		Object sharedInstance = getSingleton(beanName);
         // 缓存获取到以后,必须参数为空才行,不然参数不同,获取到的肯定不一样
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
             // 如果存在,获取对象示例 然后直接到方法末尾
             // <3> 返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身,而是返回指定方法返回的实例
			beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {// 如果没有单例BEAN,或者有BEAN并且有args参数进入此方法
             
             // <4> 特殊情况校验 
             // 多例Bean,正常创建无所谓,当存在循环依赖的时候,可能存在自己依赖自己,
             // 同时又是多例Bean,可能造成死循环,这个Spring无解,直接抛出异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

             // <5>
			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
             // 从当前容器中找不到指定名称的bean,此时递归去parentFactory查找
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
                 // 主要针对FactoryBean,将Bean的&重新加上
				String nameToLookup = originalBeanName(name);
                 // 如果parent容器依旧是AbstractBeanFactory的实例
                 // instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例
				if (parentBeanFactory instanceof AbstractBeanFactory) {
                      // 直接递归调用方法来查找
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
                      // 如果有参数,则委派父类容器根据指定名称和显示的参数查找
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
                      // 委派父级容器根据指定名称和类型查找
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
                      // 委派父级容器根据指定名称查找
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}
            
             // <6> typeCheckOnly是用来判断调用getBean()是否仅仅是为了类型检查获取bean,而不是为了创建Bean
             // 一般参数传递过来都是false
			if (!typeCheckOnly) {
                 // 标记bean为已创建
				markBeanAsCreated(beanName);
			}

			StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);
			try {
				if (requiredType != null) {
					beanCreation.tag("beanType", requiredType::toString);
				}
                  // <7> 将不同的类型的BeanDefinition都转换为RootBeanDefinition,
                  // 之前介绍了RootBeanDefinition为框架运行的默认类型
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                  // 检测Bean的定义信息
				checkMergedBeanDefinition(mbd, beanName, args);

                  // <8> 获取Bean的依赖对象 也就是创建该对象,必须保证某些对象已经创建好
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
                          // 缓存依赖调用
						registerDependentBean(dep, beanName);
						try {
                               // 先循环递归创建依赖对象
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance. 
                 // <9> 创建单例Bean
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
                               // 创建
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
                              // 创建报错就销毁这个bean
							destroySingleton(beanName);
							throw ex;
						}
					});
                      // 获取Bean示例
					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
                  // <10> 创建多实例Bean
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
                      // <11> 剩余scope类型的bean创建,用的很少,如:request、session、application等生命周期
					String scopeName = mbd.getScope();
					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, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new ScopeNotActiveException(beanName, scopeName, ex);
					}
				}
			}
			catch (BeansException ex) {
				beanCreation.tag("exception", ex.getClass().toString());
				beanCreation.tag("message", String.valueOf(ex.getMessage()));
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
			finally {
				beanCreation.end();
			}
		}

         // 对创建的Bean实例对象进行类型检查
		return adaptBeanInstance(name, beanInstance, requiredType);
	}

逻辑图

简单步骤

  1. 处理别名
  2. 尝试缓存获取
  3. 缓存中存在 && 参数为空,此时返回结果
  4. 缓存没有,那就创建Bean,首先会有一个多例Bean的循环依赖效验
  5. 处理BeanDefinition,获取最终需求的类型RootBeanDefinition
  6. 处理依赖对象depends-on
  7. 判断分别创建singletonprototype自定义scope
  8. 返回结果前需要做类型检查

详细逻辑图

《Spring系列》第8章 Bean的加载(一) getBean()_第1张图片

1.转换对应beanName

传入的参数name,可能是别名,也可能是FactoryBean,所以需要进行一系列的解析,这些解析内容包含如下内容

  • 去除FactoryBean的修饰符,也就是如果name=“&aa”,那么会首先去除&而使name=“aa”
  • 取指定的alias表示的最终beanName,例如别名A指向名称为B的bean,则返回B,若别名A指向别名B,别名B又指向名称为C的bean,则返回C

《Spring系列》第8章 Bean的加载(一) getBean()_第2张图片

transformedBeanName()

protected String transformedBeanName(String name) {
   return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

// BeanFactoryUtils#transformedBeanName()
// 返回实际的bean名称,去掉工厂的引用前缀
public static String transformedBeanName(String name) {
   Assert.notNull(name, "'name' must not be null");
   if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
      return name;
   }
   return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
      do {
         beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
      }
      while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
      return beanName;
   });
}

public String canonicalName(String name) {
   String canonicalName = name;
   // Handle aliasing...
   String resolvedName;
   // 递归获取,因为名称可能是循环引用
   do {
      // 从别名Map中获取原名称
      resolvedName = this.aliasMap.get(canonicalName);
      if (resolvedName != null) {
         canonicalName = resolvedName;
      }
   }
   while (resolvedName != null);
   return canonicalName;
}

2.尝试先从缓存获取

单例在Spring的同一个容器内只会被创建一次,后续在获取bean,就直接从单例缓存中获取了。

当然这里也只是尝试加载,首先尝试从缓存中加载,如果加载不成功则再次尝试从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,在Spring中创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光到缓存中,一旦下一个bean创建时候需要依赖上一个bean,则直接使用ObjectFactory

处理循环依赖的代码中用到了很多Map存储,这里介绍一下,为了方便程序员理解,一般用三级缓存来形容

  • singletonObjects」(一级缓存):缓存某个 beanName 对应的经过了完整生命周期的bean;
  • earlySingletonObjects」(二级缓存):缓存允许提前暴露的bean对象, 但是此时的bean还没有初始化完成,如果设置了AOP功能,那么该bean存储的就是进行了 AOP 之后得到的代理对象,但是该代理对象还没有进行属性注入和后续的BeanPostProcesso 等生命周期
  • singletonFactories」(三级缓存):缓存的是一个 ObjectFactory ,主要用来去生成原始对象进行了 AOP之后得到的「代理对象」,在每个 Bean 的生成过程中,都会提前暴露一个工厂,这个工厂可能用到,也可能用不到,如果没有出现循环依赖依赖本 bean,那么这个工厂无用,本 bean 按照自己的生命周期执行,执行完后直接把本 bean 放入 singletonObjects 中即可,如果出现了循环依赖依赖了本 bean,则另外那个 bean 执行 ObjectFactory 提交得到一个 AOP 之后的代理对象(如果有 AOP 的话,如果无需 AOP ,则直接得到一个原始对象)。
    《Spring系列》第8章 Bean的加载(一) getBean()_第3张图片

getSingleton()

	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
         // 检查一级缓存中是否存在实例
		Object singletonObject = this.singletonObjects.get(beanName);
         if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			// 如果一级缓存为空,则尝试从二级缓存获取
             singletonObject = this.earlySingletonObjects.get(beanName);
             // 二级缓存不存在 &&  allowEarlyReference允许提前暴露bean引用
			if (singletonObject == null && allowEarlyReference) {
                  synchronized (this.singletonObjects) {
					// Consistent creation of early reference within full singleton lock
                      // 加锁后,Double Check
                      singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
                          // 加锁后,Double Check
						singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {
                               // 检查三级缓存, 三级缓存时为了适配AOP,而做的特殊处理
                               ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
                                   // 通过 getObject() 获取到对象,实际上调用的是存入的 getEarlyBeanReference()
                                   // 存在AOP返回代理对象,否则返回原始对象
								singletonObject = singletonFactory.getObject();
                                   // 存入到二级缓存,三级缓存中删除
                                   this.earlySingletonObjects.put(beanName, singletonObject);
                                   this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}

3.通过Bean实例获取不同结果

getObjectForBeanInstance()是个高频率使用的方法,无论是从缓存中获取bean还是根据不同的scope策略加载bean,总之,我们得到的bean的实例后要做的第一步调用该方法来检测一下正确性,其实就是检测当前bean是否为FactoryBean类型的bean

getObjectForBeanInstance()

从缓冲中得到了bean的原始状态,则需要对bean进行实例化,主要是为了检测普通bean和FactoryBean

  1. 第一种情况 name名称带&,则代表获取的FactoryBean本身,需要判断一下类型,然后返回
  2. 第二种情况判断它是1个普通的bean,直接返回即可
  3. 第三种情况,则代码它是FactoryBean,并且名称没有&,需要通过FactoryBean#getObject()获取对应的实例
protected Object getObjectForBeanInstance(
      Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

   // Don't let calling code try to dereference the factory if the bean isn't a factory.
   // 第一种情况,名称带&,则获取的FactoryBean本身
   if (BeanFactoryUtils.isFactoryDereference(name)) {
      if (beanInstance instanceof NullBean) {
         return beanInstance;
      }
      // 如果beanInstance不是FactoryBean类型,则抛出异常
      // 因为name以&开头肯定是获取FacotoryBean类型,如果不是就异常
      if (!(beanInstance instanceof FactoryBean)) {
         throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
      }
      if (mbd != null) {
         mbd.isFactoryBean = true;
      }
      return beanInstance;
   }

   // Now we have the bean instance, which may be a normal bean or a FactoryBean.
   // If it's a FactoryBean, we use it to create a bean instance, unless the
   // caller actually wants a reference to the factory.
   // 第二种情况,代表是普通的bean,直接返回即可
   if (!(beanInstance instanceof FactoryBean)) {
      return beanInstance;
   }
	
   // 第三种情况,通过FactoryBean获取对应的实例
   Object object = null;
   // 执行到这里的,代表肯定是FactoryBean类型
   if (mbd != null) {
      mbd.isFactoryBean = true;
   } else {
      // 尝试从缓存中获取,因为FactoryBean创建的默认是单例对象,需要存起来
      object = getCachedObjectForFactoryBean(beanName);
   }
   // 其余的就是2种情况:  1)单例的,第一次创建 2)多例的,需要每次都创建
   if (object == null) {
      // Return bean instance from factory.
      FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
      // Caches object obtained from FactoryBean if it is a singleton.
      if (mbd == null && containsBeanDefinition(beanName)) {
         mbd = getMergedLocalBeanDefinition(beanName);
      }
      boolean synthetic = (mbd != null && mbd.isSynthetic());
      object = getObjectFromFactoryBean(factory, beanName, !synthetic);
   }
   return object;
}

getCachedObjectForFactoryBean()

获取FactoryBean创建的对象,因为是单例的,所以需要缓存起来

@Nullable
protected Object getCachedObjectForFactoryBean(String beanName) {
   return this.factoryBeanObjectCache.get(beanName);
}

getObjectFromFactoryBean()

FactoryBean获取bean实例,这个最底层肯定是调用getObject()方法

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
   // 单例Bean && Bean实例已经创建过, 没有再次创建的必要, 要保证单例 Bean 全局唯一, 直接从缓存中获取
   if (factory.isSingleton() && containsSingleton(beanName)) {
      synchronized (getSingletonMutex()) {
         Object object = this.factoryBeanObjectCache.get(beanName);
         // 缓存中没有,则代表第一次创建
         if (object == null) {
            // 【最底层的调用getObject()创建bean实例】
            object = doGetObjectFromFactoryBean(factory, beanName);
            // Only post-process and store if not put there already during getObject() call above
            // (e.g. because of circular reference processing triggered by custom getBean calls)
            Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
            if (alreadyThere != null) {
               object = alreadyThere;
            }
            else {
               if (shouldPostProcess) {
                  if (isSingletonCurrentlyInCreation(beanName)) {
                     // Temporarily return non-post-processed object, not storing it yet..
                     return object;
                  }
                  beforeSingletonCreation(beanName);
                  try {
                     // 执行bean的BeanPostProcessor后置处理器
                     object = postProcessObjectFromFactoryBean(object, beanName);
                  }
                  catch (Throwable ex) {
                     throw new BeanCreationException(beanName,
                           "Post-processing of FactoryBean's singleton object failed", ex);
                  }
                  finally {
                     afterSingletonCreation(beanName);
                  }
               }
               if (containsSingleton(beanName)) {
                  // 存入缓存
                  this.factoryBeanObjectCache.put(beanName, object);
               }
            }
         }
         return object;
      }
   }
   else {
      // 获取多例,每次都创建新的
      Object object = doGetObjectFromFactoryBean(factory, beanName);
      if (shouldPostProcess) {
         try {
            // 执行bean的BeanPostProcessor后置处理器
            object = postProcessObjectFromFactoryBean(object, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
         }
      }
      return object;
   }
}

4.多例Bean循环依赖检查

当多例Bean的情况下,可能会出现循环依赖,自己依赖自己的情况,这样出现死循环创建Bean,Spring针对这个是无解的,需要抛异常

那么具体如何判断呢?在这个doGetBean()中,当创建多例Bean的时候,会存入prototypesCurrentlyInCreation,代表该Bean正在创建,如果存在循环依赖,那么肯定会先判断到该步,因为之前已经缓存了,那么这里肯定可以获取到,就判断是多例Bean情况下的循环依赖,直接抛出异常

// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
   throw new BeanCurrentlyInCreationException(beanName);
}
// 通过名称看出来是为了针对bean多例的情况, 
// 单例: 全局统一, 只需要第一次创建的时候检查循环依赖, 
// 多例: 需要在每个线程创建bean的时候检查循环依赖, 这就对应了为啥类型是ThreadLocal
// prototypesCurrentlyInCreation第一次存放的是第一次请求的name字符串,第二次是存放set集合
// 每次请求bean看看set集合是否存在,如果存在代表这个bean已经创建了 但是还是需要重新创建 说明此时存在循环依赖
private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal<>("Prototype beans currently in creation");

protected boolean isPrototypeCurrentlyInCreation(String beanName) {
   Object curVal = this.prototypesCurrentlyInCreation.get();
   // 第一次检查字符串, 第二次转换成Set判断包含
   return (curVal != null && (curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
}

5.转换RootBeanDefinition

将不同类型的BeanDefinition都转成成RootBeanDefinition返回,因为Spring框架定义运行时必须使用RootBeanDefinition,这是我内部使用的统一格式

同时如果存在父子Bean的情况,需要把父Bean的属性合并到子Bean中

RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

getMergedLocalBeanDefinition()

// 方法1:
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
   // Quick check on the concurrent map first, with minimal locking.
   RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
   // 缓存获取到 && 不需要重新合并
   if (mbd != null && !mbd.stale) {
      return mbd;
   }
   return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

// 方法2:
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
      throws BeanDefinitionStoreException {

   return getMergedBeanDefinition(beanName, bd, null);
}

// 方法3:如果给定 bean 的定义是子 bean 定义,则通过与父 bean 合并,返回给定 bean 的 RootBeanDefinition。
protected RootBeanDefinition getMergedBeanDefinition(
      String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
      throws BeanDefinitionStoreException {

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

      // <1> 从已经合并的BeanDefinition缓存尝试获取
      // Check with full lock now in order to enforce the same merged instance.
      if (containingBd == null) {
         mbd = this.mergedBeanDefinitions.get(beanName);
      }

      if (mbd == null || mbd.stale) {
         previous = mbd;
         // 如果父bean为空,则代表它是一个普通的bean,直接创建RootBeanDefinition
         if (bd.getParentName() == null) {
            // Use copy of given root bean definition.
            if (bd instanceof RootBeanDefinition) {
               mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
            }
            else {
               mbd = new RootBeanDefinition(bd);
            }
         }
         else {
            // 这里代表需要把父bean中的属性合并到子bean中,用的很少就不解释了
            // Child bean definition: needs to be merged with parent.
            BeanDefinition pbd;
            try {
               String parentBeanName = transformedBeanName(bd.getParentName());
               if (!beanName.equals(parentBeanName)) {
                  pbd = getMergedBeanDefinition(parentBeanName);
               }
               else {
                  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 a ConfigurableBeanFactory parent");
                  }
               }
            }
            catch (NoSuchBeanDefinitionException ex) {
               throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                     "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
            }
            // Deep copy with overridden values.
            mbd = new RootBeanDefinition(pbd);
            mbd.overrideFrom(bd);
         }

         // 默认单例
         // Set default singleton scope, if not configured before.
         if (!StringUtils.hasLength(mbd.getScope())) {
            mbd.setScope(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.
         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)
         if (containingBd == null && isCacheBeanMetadata()) {
            this.mergedBeanDefinitions.put(beanName, mbd);
         }
      }
      if (previous != null) {
         copyRelevantMergedBeanDefinitionCaches(previous, mbd);
      }
      return mbd;
   }
}

checkMergedBeanDefinition()

BeanDefinition如果是抽象类抛出异常

protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
      throws BeanDefinitionStoreException {

   if (mbd.isAbstract()) {
      throw new BeanIsAbstractException(beanName);
   }
}

6.寻找depend依赖

判断是否存在循环depend

// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
   for (String dep : dependsOn) {
      // 校验。可能存在A依赖B,B依赖A,这样的情况抛异常,异常说明中也写了Circular depends-on,环形依赖
      if (isDependent(beanName, dep)) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
      }
      // 注册
      registerDependentBean(dep, beanName);
      try {
         // 递归初始化Bean
         getBean(dep);
      }
      catch (NoSuchBeanDefinitionException ex) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
      }
   }
}

7.创建单例Bean

// Create bean instance.
if (mbd.isSingleton()) {
   // 会通过 getSingleton()获取单例对象
   // 参数1: beanName
   // 参数2: 采用的是JDK8新特征函数式接口
   sharedInstance = getSingleton(beanName, () -> {
      try {
         // 第1步创建bean
         return createBean(beanName, mbd, args);
      }
      catch (BeansException ex) {
         // Explicitly remove instance from singleton cache: It might have been put there
         // eagerly by the creation process, to allow for circular reference resolution.
         // Also remove any beans that received a temporary reference to the bean.
         destroySingleton(beanName);
         throw ex;
      }
   });
   beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

getSingleton()

  1. 尝试从缓存中获取
  2. 若没有加载,则记录beanName的正在加载状态
  3. 通过调用参数传入的ObjectFactory的getObject()实例化bean
  4. 加载单例后的处理方法调用
  5. 将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
             // 1.加锁后再次检测缓存中是否存在
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				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 + "'");
				}
                  // 2.标记该bean处于加载中状态
				beforeSingletonCreation(beanName);
                 // 是不是新的单实例(看了半天感觉没啥用)
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
                      // 3.初始化bean,  singletonFactory是通过参数传进来的函数式接口
                      // 【在这里通过createBean()创建实例,singletonFactory是传进来的函数式接口】
					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;
					}
                      // 4.去掉该bean的加载中状态
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
                      // 5.创建完成就添加单例到缓存池
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

beforeSingletonCreation()

加载bean之前,将该beanName存入,代表该bean处于加载中的状态

protected void beforeSingletonCreation(String beanName) {
   // this.singletonsCurrentlyInCreation.add(beanName) 代表加入到集合中,代表bean正在加载
   if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
      throw new BeanCurrentlyInCreationException(beanName);
   }
}

afterSingletonCreation()

加载bean之后,将beanName取消掉加载中的状态

protected void afterSingletonCreation(String beanName) {
   if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
      throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
   }
}

addSingleton()

创建完毕,存入单例缓存,并删除各种辅助状态

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);
   }
}

8.创建多例bean

else if (mbd.isPrototype()) {
   // It's a prototype -> create a new instance.
   Object prototypeInstance = null;
   try {
      beforePrototypeCreation(beanName);
      // 创建实例bean
      prototypeInstance = createBean(beanName, mbd, args);
   }
   finally {
      afterPrototypeCreation(beanName);
   }
   beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

beforePrototypeCreation()

protected void beforePrototypeCreation(String beanName) {
   // 判断是否正在创建
   Object curVal = this.prototypesCurrentlyInCreation.get();
   if (curVal == null) {
      this.prototypesCurrentlyInCreation.set(beanName);
   }
   else if (curVal instanceof String) {
      Set<String> beanNameSet = new HashSet<>(2);
      beanNameSet.add((String) curVal);
      beanNameSet.add(beanName);
      this.prototypesCurrentlyInCreation.set(beanNameSet);
   }
   else {
      Set<String> beanNameSet = (Set<String>) curVal;
      beanNameSet.add(beanName);
   }
}

afterPrototypeCreation()

protected void afterPrototypeCreation(String beanName) {
   Object curVal = this.prototypesCurrentlyInCreation.get();
   if (curVal instanceof String) {
      this.prototypesCurrentlyInCreation.remove();
   }
   else if (curVal instanceof Set) {
      Set<String> beanNameSet = (Set<String>) curVal;
      beanNameSet.remove(beanName);
      if (beanNameSet.isEmpty()) {
         this.prototypesCurrentlyInCreation.remove();
      }
   }
}

else if (curVal instanceof String) {
Set beanNameSet = new HashSet<>(2);
beanNameSet.add((String) curVal);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);
}
else {
Set beanNameSet = (Set) curVal;
beanNameSet.add(beanName);
}
}


## afterPrototypeCreation()

```java
protected void afterPrototypeCreation(String beanName) {
   Object curVal = this.prototypesCurrentlyInCreation.get();
   if (curVal instanceof String) {
      this.prototypesCurrentlyInCreation.remove();
   }
   else if (curVal instanceof Set) {
      Set beanNameSet = (Set) curVal;
      beanNameSet.remove(beanName);
      if (beanNameSet.isEmpty()) {
         this.prototypesCurrentlyInCreation.remove();
      }
   }
}

你可能感兴趣的:(Spring,spring,java)