@ -22,6 +22,8 @@ import java.util.HashSet;
import java.util.LinkedHashSet ;
import java.util.LinkedHashSet ;
import java.util.Set ;
import java.util.Set ;
import org.apache.commons.logging.Log ;
import org.apache.commons.logging.LogFactory ;
import org.jspecify.annotations.Nullable ;
import org.jspecify.annotations.Nullable ;
import org.springframework.aop.scope.ScopedProxyUtils ;
import org.springframework.aop.scope.ScopedProxyUtils ;
@ -67,6 +69,8 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
private static final String PSEUDO_BEAN_NAME_PLACEHOLDER = "<<< PSEUDO BEAN NAME PLACEHOLDER >>>" ;
private static final String PSEUDO_BEAN_NAME_PLACEHOLDER = "<<< PSEUDO BEAN NAME PLACEHOLDER >>>" ;
private static final Log logger = LogFactory . getLog ( BeanOverrideBeanFactoryPostProcessor . class ) ;
private static final BeanNameGenerator beanNameGenerator = DefaultBeanNameGenerator . INSTANCE ;
private static final BeanNameGenerator beanNameGenerator = DefaultBeanNameGenerator . INSTANCE ;
private final Set < BeanOverrideHandler > beanOverrideHandlers ;
private final Set < BeanOverrideHandler > beanOverrideHandlers ;
@ -182,10 +186,10 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
}
}
if ( existingBeanDefinition ! = null ) {
if ( existingBeanDefinition ! = null ) {
// Validate the existing bean definition.
// Process the existing bean definition.
//
//
// Applies during "JVM runtime", "AOT processing", and "AOT runtime".
// Applies during "JVM runtime", "AOT processing", and "AOT runtime".
validateBeanDefinition ( beanFactory , beanName ) ;
convertToSingletonIfNecessary ( existingBeanDefinition , beanName ) ;
}
}
else if ( Boolean . getBoolean ( AbstractAotProcessor . AOT_PROCESSING ) ) {
else if ( Boolean . getBoolean ( AbstractAotProcessor . AOT_PROCESSING ) ) {
// There was no existing bean definition, but during "AOT processing" we
// There was no existing bean definition, but during "AOT processing" we
@ -289,7 +293,8 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
}
}
}
}
validateBeanDefinition ( beanFactory , beanName ) ;
BeanDefinition beanDefinition = beanFactory . getBeanDefinition ( beanName ) ;
convertToSingletonIfNecessary ( beanDefinition , beanName ) ;
this . beanOverrideRegistry . registerBeanOverrideHandler ( handler , beanName ) ;
this . beanOverrideRegistry . registerBeanOverrideHandler ( handler , beanName ) ;
}
}
@ -470,19 +475,20 @@ class BeanOverrideBeanFactoryPostProcessor implements BeanFactoryPostProcessor,
}
}
/ * *
/ * *
* Validate that the { @link BeanDefinition } for the supplied bean name is suitable
* Convert the supplied { @link BeanDefinition } for the supplied bean name to
* for being replaced by a bean override .
* a singleton , if necessary .
* < p > If there is no registered { @code BeanDefinition } for the supplied bean name ,
* @since 7 . 0
* no validation is performed .
* /
* /
private static void validateBeanDefinition ( ConfigurableListableBeanFactory beanFactory , String beanName ) {
private static void convertToSingletonIfNecessary ( BeanDefinition beanDefinition , String beanName ) {
// Due to https://github.com/spring-projects/spring-framework/issues/33800, we do NOT invoke
// Due to https://github.com/spring-projects/spring-framework/issues/33800, we do NOT invoke
// beanFactory.isSingleton(beanName), since doing so can result in a BeanCreationException for
// beanFactory.isSingleton(beanName), since doing so can result in a BeanCreationException for
// certain beans -- for example, a Spring Data FactoryBean for a JpaRepository.
// certain beans -- for example, a Spring Data FactoryBean for a JpaRepository.
if ( beanFactory . containsBeanDefinition ( beanName ) ) {
if ( ! beanDefinition . isSingleton ( ) ) {
BeanDefinition beanDefinition = beanFactory . getBeanDefinition ( beanName ) ;
if ( logger . isWarnEnabled ( ) ) {
Assert . state ( beanDefinition . isSingleton ( ) ,
logger . warn ( "Converting '%s' scoped bean definition '%s' to a singleton."
( ) - > "Unable to override bean '" + beanName + "': only singleton beans can be overridden." ) ;
. formatted ( beanDefinition . getScope ( ) , beanName ) ) ;
}
beanDefinition . setScope ( BeanDefinition . SCOPE_SINGLETON ) ;
}
}
}
}