diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java index 00867c7d415..056481a86db 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java @@ -315,7 +315,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements while ((singletonObject = this.singletonObjects.get(beanName)) == null) { Thread otherThread = this.currentCreationThreads.get(beanName); if (otherThread != null && (otherThread == currentThread || - this.lenientWaitingThreads.get(otherThread) == currentThread)) { + checkDependentWaitingThreads(otherThread, currentThread))) { throw ex; } if (!this.singletonsInLenientCreation.contains(beanName)) { @@ -431,6 +431,16 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements } } + private boolean checkDependentWaitingThreads(Thread waitingThread, Thread candidateThread) { + Thread threadToCheck = waitingThread; + while ((threadToCheck = this.lenientWaitingThreads.get(threadToCheck)) != null) { + if (threadToCheck == candidateThread) { + return true; + } + } + return false; + } + /** * Determine whether the current thread is allowed to hold the singleton lock. *
By default, any thread may acquire and hold the singleton lock, except
diff --git a/spring-context/src/test/java/org/springframework/context/annotation/BackgroundBootstrapTests.java b/spring-context/src/test/java/org/springframework/context/annotation/BackgroundBootstrapTests.java
index 3d7662ec44e..a0731445314 100644
--- a/spring-context/src/test/java/org/springframework/context/annotation/BackgroundBootstrapTests.java
+++ b/spring-context/src/test/java/org/springframework/context/annotation/BackgroundBootstrapTests.java
@@ -139,7 +139,7 @@ class BackgroundBootstrapTests {
Thread.sleep(1000);
}
catch (InterruptedException ex) {
- throw new RuntimeException(ex);
+ Thread.currentThread().interrupt();
}
return new TestBean();
}
@@ -150,7 +150,7 @@ class BackgroundBootstrapTests {
Thread.sleep(2000);
}
catch (InterruptedException ex) {
- throw new RuntimeException(ex);
+ Thread.currentThread().interrupt();
}
return new TestBean();
}
@@ -170,7 +170,7 @@ class BackgroundBootstrapTests {
Thread.sleep(1000);
}
catch (InterruptedException ex) {
- throw new RuntimeException(ex);
+ Thread.currentThread().interrupt();
}
return new TestBean();
}
@@ -191,7 +191,7 @@ class BackgroundBootstrapTests {
Thread.sleep(2000);
}
catch (InterruptedException ex) {
- throw new RuntimeException(ex);
+ Thread.currentThread().interrupt();
}
return new TestBean();
}
@@ -208,7 +208,7 @@ class BackgroundBootstrapTests {
Thread.sleep(1000);
}
catch (InterruptedException ex) {
- throw new RuntimeException(ex);
+ Thread.currentThread().interrupt();
}
return new TestBean("testBean1");
}
@@ -230,7 +230,7 @@ class BackgroundBootstrapTests {
Thread.sleep(1000);
}
catch (InterruptedException ex) {
- throw new RuntimeException(ex);
+ Thread.currentThread().interrupt();
}
return new TestBean();
}
@@ -241,7 +241,7 @@ class BackgroundBootstrapTests {
Thread.sleep(2000);
}
catch (InterruptedException ex) {
- throw new RuntimeException(ex);
+ Thread.currentThread().interrupt();
}
return new TestBean();
}
@@ -253,37 +253,25 @@ class BackgroundBootstrapTests {
@Bean
public TestBean testBean1(ObjectProvider