Spring
是线程安全的,支持多线程并发调用。但在某种特殊情况下,使用 BeanFactory
的 getBean
方法,我成功拿到了未经初始化的 Bean
(是BUG,亦或是出于某种原因考虑的特性?)。
一、获取到的 Bean 为什么未初始化?
通过 getBean
获取到未经过初始化的 Bean
需要满足如下的场景:
Bean
开启了懒加载:否则调用getBean
前Bean
已经初始化好了;- 该
Bean
与其他Bean
产生了循环依赖:未经初始化问题来自于二级缓存earlySingletonObjects
; - 有两个及以上的线程同时调用
getBean
方法获取该Bean
:并发场景出现的问题。
关键代码片段:
protected Object getSingleton(String beanName, boolean allowEarlyReference) {// Quick check for existing instance without full singleton lockObject singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {synchronized (this.singletonObjects) {// Consistent creation of early reference within full singleton locksingletonObject = this.singletonObjects.get(beanName);if (singletonObject