Notify lenientCreationFinished condition after locked creation as well
Closes gh-34522
This commit is contained in:
parent
108caea385
commit
d2733cea36
|
@ -253,7 +253,6 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
|||
Boolean lockFlag = isCurrentThreadAllowedToHoldSingletonLock();
|
||||
boolean acquireLock = !Boolean.FALSE.equals(lockFlag);
|
||||
boolean locked = (acquireLock && this.singletonLock.tryLock());
|
||||
boolean lenient = false;
|
||||
try {
|
||||
Object singletonObject = this.singletonObjects.get(beanName);
|
||||
if (singletonObject == null) {
|
||||
|
@ -268,7 +267,6 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
|||
Thread.currentThread().getName() + "\" while other thread holds " +
|
||||
"singleton lock for other beans " + this.singletonsCurrentlyInCreation);
|
||||
}
|
||||
lenient = true;
|
||||
this.lenientCreationLock.lock();
|
||||
try {
|
||||
this.singletonsInLenientCreation.add(beanName);
|
||||
|
@ -329,7 +327,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
|||
// Try late locking for waiting on specific bean to be finished.
|
||||
this.singletonLock.lock();
|
||||
locked = true;
|
||||
// Singleton object should have appeared in the meantime.
|
||||
// Lock-created singleton object should have appeared in the meantime.
|
||||
singletonObject = this.singletonObjects.get(beanName);
|
||||
if (singletonObject != null) {
|
||||
return singletonObject;
|
||||
|
@ -343,9 +341,13 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
|||
this.suppressedExceptions = new LinkedHashSet<>();
|
||||
}
|
||||
try {
|
||||
// Leniently created singleton object could have appeared in the meantime.
|
||||
singletonObject = this.singletonObjects.get(beanName);
|
||||
if (singletonObject == null) {
|
||||
singletonObject = singletonFactory.getObject();
|
||||
newSingleton = true;
|
||||
}
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
// Has the singleton object implicitly appeared in the meantime ->
|
||||
// if yes, proceed with it since the exception indicates that state.
|
||||
|
@ -388,7 +390,6 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
|||
if (locked) {
|
||||
this.singletonLock.unlock();
|
||||
}
|
||||
if (lenient) {
|
||||
this.lenientCreationLock.lock();
|
||||
try {
|
||||
this.singletonsInLenientCreation.remove(beanName);
|
||||
|
@ -399,7 +400,6 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the current thread is allowed to hold the singleton lock.
|
||||
|
|
|
@ -56,6 +56,16 @@ class BackgroundBootstrapTests {
|
|||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(5)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
void bootstrapWithCircularReference() {
|
||||
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(CircularReferenceBeanConfig.class);
|
||||
ctx.getBean("testBean1", TestBean.class);
|
||||
ctx.getBean("testBean2", TestBean.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Timeout(5)
|
||||
@EnabledForTestGroups(LONG_RUNNING)
|
||||
|
@ -138,6 +148,34 @@ class BackgroundBootstrapTests {
|
|||
}
|
||||
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CircularReferenceBeanConfig {
|
||||
|
||||
@Bean
|
||||
public TestBean testBean1(ObjectProvider<TestBean> testBean2) {
|
||||
new Thread(testBean2::getObject).start();
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
return new TestBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TestBean testBean2(TestBean testBean1) {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
return new TestBean();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomExecutorBeanConfig {
|
||||
|
||||
|
|
Loading…
Reference in New Issue