Reinstate Bean Override support for replacing a manually registered singleton

Closes gh-33678
This commit is contained in:
Sam Brannen
2024-10-09 17:53:41 +02:00
parent c70a6d3be1
commit 8d652e9c12
2 changed files with 79 additions and 1 deletions

View File

@@ -128,7 +128,11 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
if (beanName != null) {
// We are overriding an existing bean by-type.
beanName = BeanFactoryUtils.transformedBeanName(beanName);
existingBeanDefinition = beanFactory.getBeanDefinition(beanName);
// If we are overriding a manually registered singleton, we won't find
// an existing bean definition.
if (beanFactory.containsBeanDefinition(beanName)) {
existingBeanDefinition = beanFactory.getBeanDefinition(beanName);
}
}
else {
// We will later generate a name for the nonexistent bean, but since NullAway
@@ -150,6 +154,12 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
}
}
// Ensure we don't have any manually registered singletons registered, since we
// register a bean override instance as a manual singleton at the end of this method.
if (beanFactory.containsSingleton(beanName)) {
destroySingleton(beanFactory, beanName);
}
if (existingBeanDefinition != null) {
// Validate the existing bean definition.
//
@@ -333,6 +343,10 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
// Since the isSingleton() check above may have registered a singleton as a side
// effect -- for example, for a FactoryBean -- we need to destroy the singleton,
// because we later manually register a bean override instance as a singleton.
destroySingleton(beanFactory, beanName);
}
private static void destroySingleton(ConfigurableListableBeanFactory beanFactory, String beanName) {
if (beanFactory instanceof DefaultListableBeanFactory dlbf) {
dlbf.destroySingleton(beanName);
}