Why @Configuration + @Bean Overrides @Component in Spring Boot and How Bean Definition Overriding Evolved
This article explains why, in Spring Boot 2.0.3, a bean defined with @Configuration + @Bean replaces a @Component‑annotated bean of the same type, shows how to verify which bean is instantiated, and describes the framework’s evolution—including the allowBeanDefinitionOverriding setting—that gives developers control over bean overriding behavior.
The author discovered that a @Configuration class defining a @Bean for UserManager (with a non‑null userName ) co‑existed with a @Component class of the same type (with a null userName ) in a Spring Boot 2.0.3 project. When other components injected UserManager , the injected instance was the one created by the @Configuration bean, not the @Component one.
To verify the behavior, the author debugged the application and added logging to the constructors. Only the constructor called by the @Bean method was executed, confirming that a single UserManager bean existed and it was the one from the configuration class.
The underlying reason is that during the container refresh, Spring first registers beans discovered by component scanning (including the @Component bean). Later, when processing @Configuration classes, the ConfigurationClassPostProcessor creates a ConfigurationClassBeanDefinition for each @Bean method and registers it, overriding any existing bean definition with the same name. This replacement is logged at INFO level, e.g.: 2021-10-03 20:37:33.697 INFO 13600 --- [main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'userManager' with a different definition: replacing [Generic bean: class [com.lee.qsl.manager.UserManager]...] with [Root bean: class [null]; factoryBeanName=userConfig; factoryMethodName=userManager]
Spring 5.0.7 (used by Spring Boot 2.0.3) allowed this overriding silently. Starting with Spring 5.1.2 and Spring Boot 2.1.0, the framework introduced the allowBeanDefinitionOverriding property, giving developers the option to enable or disable bean overriding. By default, Spring still permits overriding, but Spring Boot disables it unless the property spring.main.allow-bean-definition-overriding=true is set.
The article concludes that the observed behavior is expected: the @Configuration + @Bean definition wins over the @Component definition, and developers can control this via the new configuration flag.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.