Skip to content

Commit 755721f

Browse files
committed
Avoid full singleton lock for getSingleton(beanName, false)
Closes gh-25667 (cherry picked from commit d8c420a)
1 parent 0ecdf0b commit 755721f

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
8181
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
8282

8383
/** Cache of early singleton objects: bean name to bean instance. */
84-
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
84+
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
8585

8686
/** Set of registered singletons, containing the bean names in registration order. */
8787
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
@@ -178,16 +178,24 @@ public Object getSingleton(String beanName) {
178178
*/
179179
@Nullable
180180
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
181+
// Quick check for existing instance without full singleton lock
181182
Object singletonObject = this.singletonObjects.get(beanName);
182183
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
183-
synchronized (this.singletonObjects) {
184-
singletonObject = this.earlySingletonObjects.get(beanName);
185-
if (singletonObject == null && allowEarlyReference) {
186-
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
187-
if (singletonFactory != null) {
188-
singletonObject = singletonFactory.getObject();
189-
this.earlySingletonObjects.put(beanName, singletonObject);
190-
this.singletonFactories.remove(beanName);
184+
singletonObject = this.earlySingletonObjects.get(beanName);
185+
if (singletonObject == null && allowEarlyReference) {
186+
synchronized (this.singletonObjects) {
187+
// Consistent creation of early reference within full singleton lock
188+
singletonObject = this.singletonObjects.get(beanName);
189+
if (singletonObject == null) {
190+
singletonObject = this.earlySingletonObjects.get(beanName);
191+
if (singletonObject == null) {
192+
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
193+
if (singletonFactory != null) {
194+
singletonObject = singletonFactory.getObject();
195+
this.earlySingletonObjects.put(beanName, singletonObject);
196+
this.singletonFactories.remove(beanName);
197+
}
198+
}
191199
}
192200
}
193201
}

0 commit comments

Comments
 (0)