Avoid Scope.registerDestructionCallback for inner beans in case of scope mismatch
This commit refines getMergedBeanDefinition's scope adaptation algorithm for inner beans, never leaving a custom scope within a containing bean of a different scope. The inner bean's scope will either be aligned with the containing bean's scope (matching the effective state) or be switched to prototype in case of an outer singleton (indicating that no singleton state management is desired). Issue: SPR-13739
This commit is contained in:
@@ -1062,7 +1062,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
String scopeName = mbd.getScope();
|
||||
Scope scope = this.scopes.get(scopeName);
|
||||
if (scope == null) {
|
||||
throw new IllegalStateException("No Scope SPI registered for scope '" + scopeName + "'");
|
||||
throw new IllegalStateException("No Scope SPI registered for scope name '" + scopeName + "'");
|
||||
}
|
||||
Object bean = scope.remove(beanName);
|
||||
if (bean != null) {
|
||||
@@ -1251,15 +1251,14 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
|
||||
// Set default singleton scope, if not configured before.
|
||||
if (!StringUtils.hasLength(mbd.getScope())) {
|
||||
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
|
||||
mbd.setScope(BeanDefinition.SCOPE_SINGLETON);
|
||||
}
|
||||
|
||||
// A bean contained in a non-singleton bean cannot be a singleton itself.
|
||||
// Let's correct this on the fly here, since this might be the result of
|
||||
// parent-child merging for the outer bean, in which case the original inner bean
|
||||
// definition will not have inherited the merged outer bean's singleton status.
|
||||
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
|
||||
mbd.setScope(containingBd.getScope());
|
||||
// Check for a mismatch between an inner bean's scope and its containing
|
||||
// bean's scope: For example, a bean contained in a non-singleton bean
|
||||
// cannot be a singleton itself. Let's correct this on the fly here.
|
||||
if (containingBd != null && !mbd.isPrototype() && !mbd.getScope().equals(containingBd.getScope())) {
|
||||
mbd.setScope(containingBd.isSingleton() ? BeanDefinition.SCOPE_PROTOTYPE : containingBd.getScope());
|
||||
}
|
||||
|
||||
// Only cache the merged bean definition if we're already about to create an
|
||||
@@ -1638,7 +1637,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
// A bean with a custom scope...
|
||||
Scope scope = this.scopes.get(mbd.getScope());
|
||||
if (scope == null) {
|
||||
throw new IllegalStateException("No Scope registered for scope '" + mbd.getScope() + "'");
|
||||
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
|
||||
}
|
||||
scope.registerDestructionCallback(beanName,
|
||||
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
|
||||
|
||||
Reference in New Issue
Block a user