Avoid full singleton lock for getSingleton(beanName, false)
Closes gh-25667
(cherry picked from commit d8c420ab75)
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user