Call setAllowBeanDefinitionOverriding before initializer

Update initialization order in `SpringApplication` to ensure
`setAllowBeanDefinitionOverriding` is called before initializiers.

This prevents an initializer from accidentially overriding a bean.

Closes gh-50264
This commit is contained in:
Phillip Webb
2026-05-04 15:47:22 -07:00
parent 796b0343c6
commit bcf4c32426
2 changed files with 24 additions and 7 deletions
@@ -383,6 +383,13 @@ public class SpringApplication {
context.setEnvironment(environment);
postProcessApplicationContext(context);
addAotGeneratedInitializerIfNecessary(this.initializers);
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
if (beanFactory instanceof AbstractAutowireCapableBeanFactory autowireCapableBeanFactory) {
autowireCapableBeanFactory.setAllowCircularReferences(this.properties.isAllowCircularReferences());
if (beanFactory instanceof DefaultListableBeanFactory listableBeanFactory) {
listableBeanFactory.setAllowBeanDefinitionOverriding(this.properties.isAllowBeanDefinitionOverriding());
}
}
applyInitializers(context);
listeners.contextPrepared(context);
bootstrapContext.close(context);
@@ -391,17 +398,10 @@ public class SpringApplication {
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof AbstractAutowireCapableBeanFactory autowireCapableBeanFactory) {
autowireCapableBeanFactory.setAllowCircularReferences(this.properties.isAllowCircularReferences());
if (beanFactory instanceof DefaultListableBeanFactory listableBeanFactory) {
listableBeanFactory.setAllowBeanDefinitionOverriding(this.properties.isAllowBeanDefinitionOverriding());
}
}
if (this.properties.isLazyInitialization()) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
@@ -49,6 +49,7 @@ import org.springframework.aot.AotDetector;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanRegistrar;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.beans.factory.annotation.Autowired;
@@ -100,6 +101,7 @@ import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
@@ -1139,6 +1141,21 @@ class SpringApplicationTests {
.isThrownBy(() -> new SpringApplication(ExampleConfig.class, OverrideConfig.class).run());
}
@Test
void beanDefinitionOverridingIsAppliedToInitializer() { // gh-50264
assertThatExceptionOfType(BeanDefinitionOverrideException.class).isThrownBy(() -> {
BeanRegistrar registrar = (registry, env) -> {
registry.registerBean("someBean", String.class);
registry.registerBean("someBean", String.class);
};
ApplicationContextInitializer<GenericApplicationContext> initializer = (context) -> context
.register(registrar);
SpringApplication application = new SpringApplication(Example.class);
application.setInitializers(List.of(initializer));
application.run();
});
}
@Test
void beanDefinitionOverridingCanBeEnabled() {
assertThat(new SpringApplication(ExampleConfig.class, OverrideConfig.class)