Revise FactoryBean locking behavior for strict/lenient consistency
After the bootstrap phase (and with spring.locking.strict=true during the bootstrap phase), getSingletonFactoryBeanForTypeCheck always locks. In a background bootstrap thread, it never locks. Otherwise, it tries locking and explicitly resolves the bean class for subsequent type-based resolution (even for a component-scanned class) when it fails to acquire the lock. Furthermore, getObjectFromFactoryBean follows the same locking algorithm for post-processing.
Closes gh-34902
@ -997,9 +997,17 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
@@ -997,9 +997,17 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
@ -271,13 +271,15 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
@@ -271,13 +271,15 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
// Fallback as of 6.2: process given singleton bean outside of singleton lock.
// Thread-safe exposure is still guaranteed, there is just a risk of collisions
// when triggering creation of other beans as dependencies of the current bean.
if(logger.isInfoEnabled()){
logger.info("Obtaining singleton bean '"+beanName+"' in thread \""+
Thread.currentThread().getName()+"\" while other thread holds "+
"singleton lock for other beans "+this.singletonsCurrentlyInCreation);
@ -118,7 +118,15 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
@@ -118,7 +118,15 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
@ -131,11 +139,13 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
@@ -131,11 +139,13 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
}
else{
if(shouldPostProcess){
if(isSingletonCurrentlyInCreation(beanName)){
// Temporarily return non-post-processed object, not storing it yet
returnobject;
if(locked){
if(isSingletonCurrentlyInCreation(beanName)){
// Temporarily return non-post-processed object, not storing it yet
@ -144,7 +154,9 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
@@ -144,7 +154,9 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
"Post-processing of FactoryBean's singleton object failed",ex);
}
finally{
afterSingletonCreation(beanName);
if(locked){
afterSingletonCreation(beanName);
}
}
}
if(containsSingleton(beanName)){
@ -155,7 +167,9 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
@@ -155,7 +167,9 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg