|
|
|
@ -81,7 +81,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements |
|
|
|
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); |
|
|
|
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); |
|
|
|
|
|
|
|
|
|
|
|
/** Cache of early singleton objects: bean name to bean instance. */ |
|
|
|
/** Cache of early singleton objects: bean name to bean instance. */ |
|
|
|
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); |
|
|
|
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16); |
|
|
|
|
|
|
|
|
|
|
|
/** Set of registered singletons, containing the bean names in registration order. */ |
|
|
|
/** Set of registered singletons, containing the bean names in registration order. */ |
|
|
|
private final Set<String> registeredSingletons = new LinkedHashSet<>(256); |
|
|
|
private final Set<String> registeredSingletons = new LinkedHashSet<>(256); |
|
|
|
@ -178,16 +178,24 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
protected Object getSingleton(String beanName, boolean allowEarlyReference) { |
|
|
|
protected Object getSingleton(String beanName, boolean allowEarlyReference) { |
|
|
|
|
|
|
|
// Quick check for existing instance without full singleton lock
|
|
|
|
Object singletonObject = this.singletonObjects.get(beanName); |
|
|
|
Object singletonObject = this.singletonObjects.get(beanName); |
|
|
|
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { |
|
|
|
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { |
|
|
|
synchronized (this.singletonObjects) { |
|
|
|
singletonObject = this.earlySingletonObjects.get(beanName); |
|
|
|
singletonObject = this.earlySingletonObjects.get(beanName); |
|
|
|
if (singletonObject == null && allowEarlyReference) { |
|
|
|
if (singletonObject == null && allowEarlyReference) { |
|
|
|
synchronized (this.singletonObjects) { |
|
|
|
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); |
|
|
|
// Consistent creation of early reference within full singleton lock
|
|
|
|
if (singletonFactory != null) { |
|
|
|
singletonObject = this.singletonObjects.get(beanName); |
|
|
|
singletonObject = singletonFactory.getObject(); |
|
|
|
if (singletonObject == null) { |
|
|
|
this.earlySingletonObjects.put(beanName, singletonObject); |
|
|
|
singletonObject = this.earlySingletonObjects.get(beanName); |
|
|
|
this.singletonFactories.remove(beanName); |
|
|
|
if (singletonObject == null) { |
|
|
|
|
|
|
|
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); |
|
|
|
|
|
|
|
if (singletonFactory != null) { |
|
|
|
|
|
|
|
singletonObject = singletonFactory.getObject(); |
|
|
|
|
|
|
|
this.earlySingletonObjects.put(beanName, singletonObject); |
|
|
|
|
|
|
|
this.singletonFactories.remove(beanName); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|