Skip to content

Commit 467d5f3

Browse files
committed
Try late locking for waiting on specific bean to be finished
Closes spring-projectsgh-34186
1 parent 172c25f commit 467d5f3

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

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

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -279,7 +279,25 @@ public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
279279
if (logger.isDebugEnabled()) {
280280
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
281281
}
282-
beforeSingletonCreation(beanName);
282+
283+
try {
284+
beforeSingletonCreation(beanName);
285+
}
286+
catch (BeanCurrentlyInCreationException ex) {
287+
if (locked) {
288+
throw ex;
289+
}
290+
// Try late locking for waiting on specific bean to be finished.
291+
this.singletonLock.lock();
292+
locked = true;
293+
// Singleton object should have appeared in the meantime.
294+
singletonObject = this.singletonObjects.get(beanName);
295+
if (singletonObject != null) {
296+
return singletonObject;
297+
}
298+
beforeSingletonCreation(beanName);
299+
}
300+
283301
boolean newSingleton = false;
284302
boolean recordSuppressedExceptions = (locked && this.suppressedExceptions == null);
285303
if (recordSuppressedExceptions) {

spring-beans/src/test/java/org/springframework/beans/factory/BeanFactoryLockingTests.java

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@
2323
import org.springframework.beans.testfixture.beans.TestBean;
2424

2525
import static org.assertj.core.api.Assertions.assertThat;
26-
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
2726

2827
/**
2928
* @author Juergen Hoeller
@@ -56,9 +55,6 @@ public void setBeanFactory(BeanFactory beanFactory) {
5655
@Override
5756
public void afterPropertiesSet() throws Exception {
5857
Thread thread = new Thread(() -> {
59-
// Fail for circular reference from other thread
60-
assertThatExceptionOfType(BeanCurrentlyInCreationException.class).isThrownBy(() ->
61-
beanFactory.getBean(ThreadDuringInitialization.class));
6258
// Leniently create unrelated other bean outside of singleton lock
6359
assertThat(beanFactory.getBean(TestBean.class).getName()).isEqualTo("tb");
6460
// Creation attempt in other thread was successful

0 commit comments

Comments
 (0)