diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java index 0883637d23b..b30081b8941 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java @@ -130,7 +130,17 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg try { Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { - object = doGetObjectFromFactoryBean(factory, beanName); + if (locked) { + // The common case: within general singleton lock. + object = doGetObjectFromFactoryBean(factory, beanName); + } + else { + // Fall back to local synchronization on the given FactoryBean instance, + // as a defensive measure for non-thread-safe FactoryBean implementations. + synchronized (factory) { + object = doGetObjectFromFactoryBean(factory, beanName); + } + } // Only post-process and store if not put there already during getObject() call above // (for example, because of circular reference processing triggered by custom getBean calls) Object alreadyThere = this.factoryBeanObjectCache.get(beanName);