单例的
-
factory.isSingleton() && this.containsSingleton(beanName)
: 首先检查工厂是否生产单例对象,并且在 Spring 容器中是否包含该单例对象的定义。 -
synchronized(this.getSingletonMutex())
: 进入同步块,确保在多线程环境下对单例对象的处理是线程安全的。getSingletonMutex
方法返回一个用于同步的对象,以避免并发问题。 -
Object object = this.factoryBeanObjectCache.get(beanName);
: 尝试从单例缓存中获取对象,如果存在,表示该对象已经被创建过,并且可能已经被后处理过。如果缓存中有,直接返回该对象。 -
object = this.doGetObjectFromFactoryBean(factory, beanName);
: 如果缓存中没有对象,调用doGetObjectFromFactoryBean
方法从FactoryBean
中获取对象、 -
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
: 再次尝试从单例缓存中获取对象,以确保在doGetObjectFromFactoryBean
过程中没有其他线程已经将对象放入缓存。如果在这之间已经有其他线程将对象放入缓存,那么直接使用那个对象。 -
if (shouldPostProcess)
: 如果需要进行后处理(shouldPostProcess
为true
),则继续进行后面的处理。 -
if (this.isSingletonCurrentlyInCreation(beanName))
: 在进行后处理之前,检查该单例对象是否当前正在创建中。如果是,说明可能存在循环引用,直接返回之前获取的对象,避免进一步后处理。 -
this.beforeSingletonCreation(beanName);
: 在进行后处理之前,调用beforeSingletonCreation
方法,将当前单例对象标记为正在创建中。 -
object = this.postProcessObjectFromFactoryBean(object, beanName);
: 进行后处理,调用postProcessObjectFromFactoryBean
方法对对象进行处理。 -
finally { this.afterSingletonCreation(beanName); }
: 在try
块结束后,无论后处理是否成功,都会调用afterSingletonCreation
方法,标记单例对象已经创建完成。 -
if (this.containsSingleton(beanName)) { this.factoryBeanObjectCache.put(beanName, object); }
: 最后,如果容器中仍然包含该单例对象的定义,将对象放入单例缓存中,以便后续直接获取。
整个逻辑保证了在多线程环境中对单例对象的创建和后处理是线程安全的,并且处理了可能的循环引用问题。
非单例的