Merge branch '6.2.x'

# Conflicts:
#	spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java
This commit is contained in:
Juergen Hoeller 2025-10-03 17:34:42 +02:00
commit 2170b40213
1 changed files with 34 additions and 39 deletions

View File

@ -132,53 +132,48 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
try { try {
// A SmartFactoryBean may return multiple object types -> do not cache. // A SmartFactoryBean may return multiple object types -> do not cache.
boolean smart = (factory instanceof SmartFactoryBean<?>); boolean smart = (factory instanceof SmartFactoryBean<?>);
Object object = (!smart ? this.factoryBeanObjectCache.get(beanName) : null); // Defensively synchronize against non-thread-safe FactoryBean.getObject() implementations,
if (object == null) { // potentially to be called from a background thread while the main thread currently calls
if (locked) { // the same getObject() method within the singleton lock.
// The common case: within general singleton lock. synchronized (factory) {
Object object = (!smart ? this.factoryBeanObjectCache.get(beanName) : null);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, requiredType, beanName); object = doGetObjectFromFactoryBean(factory, requiredType, beanName);
} // Only post-process and store if not put there already during getObject() call above
else { // (for example, because of circular reference processing triggered by custom getBean calls)
// Fall back to local synchronization on the given FactoryBean instance, Object alreadyThere = (!smart ? this.factoryBeanObjectCache.get(beanName) : null);
// as a defensive measure for non-thread-safe FactoryBean implementations. if (alreadyThere != null) {
synchronized (factory) { object = alreadyThere;
object = doGetObjectFromFactoryBean(factory, requiredType, beanName);
} }
} else {
// Only post-process and store if not put there already during getObject() call above if (shouldPostProcess) {
// (for example, because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = (!smart ? this.factoryBeanObjectCache.get(beanName) : null);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
if (locked) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet
return object;
}
beforeSingletonCreation(beanName);
}
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
if (locked) { if (locked) {
afterSingletonCreation(beanName); if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet
return object;
}
beforeSingletonCreation(beanName);
}
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
if (locked) {
afterSingletonCreation(beanName);
}
} }
} }
} if (!smart && containsSingleton(beanName)) {
if (!smart && containsSingleton(beanName)) { this.factoryBeanObjectCache.put(beanName, object);
this.factoryBeanObjectCache.put(beanName, object); }
} }
} }
return object;
} }
return object;
} }
finally { finally {
if (locked) { if (locked) {