How to resolve Spring Boot @Primary annotation overriding unexpected beans
Problem
When I run my Spring Boot application with multiple ProductConfig beans, I get this error:
Description:
Parameter 0 of constructor in com.example.ProductService required a bean of type 'com.example.ProductConfig' that could not be found.Action:
Consider defining a bean of type 'com.example.ProductConfig' in your configuration.Environment
- Spring Boot 3.2.0
- Java 21
- Maven 3.8.1
What happened?
I was working on my product service and configuration setup. Here’s my original configuration:
@Configurationpublic class AppConfig {
@Bean public ProductConfig productConfig() { return new ProductConfig("default-config"); }}And here’s my service:
@Service@Primarypublic class ProductService { private final ProductConfig productConfig;
public ProductService(ProductConfig productConfig) { this.productConfig = productConfig; }
// Service methods}I can explain the key parts:
@Configurationmarks AppConfig as a Spring configuration class@Beancreates a ProductConfig bean in the Spring context@Servicemarks ProductService as a Spring service component@Primarywas supposed to make ProductService the primary implementation
But when I started my application, I got the error about ProductConfig bean not being found. I was confused because I had defined ProductConfig as a bean in AppConfig.
How to solve it?
I tried removing the @Primary annotation from ProductService:
@Servicepublic class ProductService { private final ProductConfig productConfig;
public ProductService(ProductConfig productConfig) { this.productConfig = productConfig; }}That fixed the immediate error, but then I noticed something strange. When I injected ProductConfig into other services, it wasn’t using the default configuration I expected.
So I tried adding a @Qualifier annotation to specify which bean I wanted:
@Configurationpublic class AppConfig {
@Bean @Qualifier("defaultProductConfig") public ProductConfig productConfig() { return new ProductConfig("default-config"); }}And updated my service to use the qualifier:
@Servicepublic class ProductService { private final ProductConfig productConfig;
public ProductService( @Qualifier("defaultProductConfig") ProductConfig productConfig) { this.productConfig = productConfig; }}Now test again:
mvn spring-boot:runYou can see that I succeeded to resolve the bean dependency issue.
The reason
I think the key reason for the error is:
@Primaryannotation affects all beans of the same type, not just the one it’s attached to- When ProductService has
@Primary, Spring treats it as the primary bean for ProductService type - When Spring looks for ProductConfig, it finds the ProductService bean (which is a ProductService, not ProductConfig)
- This creates a confusion in the dependency injection resolution
The @Primary annotation creates a precedence system where:
@Primarybeans get highest priority for autowiring- Without
@Qualifier, Spring picks the first matching bean it finds - This means
@Primaryon ProductService was interfering with ProductConfig injection
Summary
In this post, I showed how to resolve Spring Boot bean override issues when @Primary annotation causes unexpected dependency injection. The key point is to use @Qualifier for explicit bean selection and avoid overusing @Primary annotation.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments