前言
当获取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);
}
逻辑图
简单步骤
- 处理别名
- 尝试缓存获取
- 缓存中存在 && 参数为空,此时返回结果
- 缓存没有,那就创建Bean,首先会有一个多例Bean的循环依赖效验
- 处理
BeanDefinition
,获取最终需求的类型RootBeanDefinition
- 处理依赖对象
depends-on
- 判断分别创建
singleton
、prototype
,自定义scope
- 返回结果前需要做类型检查
详细逻辑图
1.转换对应beanName
传入的参数name,可能是别名,也可能是FactoryBean,所以需要进行一系列的解析,这些解析内容包含如下内容
- 去除
FactoryBean
的修饰符,也就是如果name=“&aa”,那么会首先去除&而使name=“aa” - 取指定的alias表示的最终beanName,例如别名A指向名称为B的bean,则返回B,若别名A指向别名B,别名B又指向名称为C的bean,则返回C
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 ,则直接得到一个原始对象)。
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
- 第一种情况
name
名称带&
,则代表获取的FactoryBean
本身,需要判断一下类型,然后返回 - 第二种情况判断它是1个普通的bean,直接返回即可
- 第三种情况,则代码它是
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()
- 尝试从缓存中获取
- 若没有加载,则记录beanName的正在加载状态
- 通过调用参数传入的ObjectFactory的
getObject()
实例化bean - 加载单例后的处理方法调用
- 将结果记录至缓存并删除加载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<String> beanNameSet = (Set<String>) curVal;
beanNameSet.remove(beanName);
if (beanNameSet.isEmpty()) {
this.prototypesCurrentlyInCreation.remove();
}
}
}