Spring Boot
Bean Override
Primary Annotation
Spring Framework
Java Development

Spring boot 2.1 bean override vs. Primary

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Bean overriding and @Primary solve different Spring problems, even though they both come up when multiple beans seem to be competing. Overriding replaces one bean definition with another bean of the same name, while @Primary tells Spring which bean to prefer when several beans of the same type are candidates for injection.

What Bean Overriding Means

Bean overriding is about bean definitions, not injection preference. If two beans are registered with the same name, one can replace the other only if overriding is allowed.

In Spring Boot 2.1, bean definition overriding is disabled by default. That means the application usually fails fast instead of silently replacing one bean with another.

properties
spring.main.allow-bean-definition-overriding=true

With that property enabled, a later bean definition with the same name can replace the earlier one. Without it, Spring Boot 2.1 usually throws an error during startup.

What @Primary Means

@Primary does not replace any bean definition. It only resolves ambiguity when multiple beans of the same type are available for autowiring.

java
1import org.springframework.context.annotation.Bean;
2import org.springframework.context.annotation.Configuration;
3import org.springframework.context.annotation.Primary;
4
5@Configuration
6public class AppConfig {
7
8    @Bean
9    public MessageService emailService() {
10        return new EmailMessageService();
11    }
12
13    @Bean
14    @Primary
15    public MessageService smsService() {
16        return new SmsMessageService();
17    }
18}

If some other bean injects MessageService, Spring chooses smsService by default because it is marked @Primary.

Both beans still exist in the container. Nothing was overridden.

The Core Difference

Think of the two mechanisms this way:

  • bean overriding decides whether one named bean definition can replace another named bean definition
  • '@Primary decides which bean to inject when multiple beans of the same type are valid'

Those are related only in the broad sense that both affect "which bean gets used." Under the hood, they solve different stages of the container lifecycle.

Example Where @Primary Helps

java
1import org.springframework.stereotype.Service;
2
3@Service
4public class NotificationRunner {
5    private final MessageService messageService;
6
7    public NotificationRunner(MessageService messageService) {
8        this.messageService = messageService;
9    }
10}

If both emailService and smsService are present and neither is primary, injection is ambiguous unless you use @Qualifier. Marking one as @Primary resolves that ambiguity cleanly.

Example Where Overriding Matters

If a library defines a bean named objectMapper and your application also defines a bean with the exact same name, @Primary does not solve the collision. That is a bean-definition conflict, not a type-selection problem.

In that case, you either:

  • rename one of the beans
  • allow bean overriding explicitly
  • use another customization hook provided by the library

Using @Primary there would leave both definitions intact and would not address the duplicate-name startup error.

Common Pitfalls

The biggest pitfall is using @Primary when the real problem is duplicate bean names. @Primary only helps during injection; it does not allow one bean definition to replace another.

Another common mistake is enabling bean overriding as a quick fix when the real issue is unclear configuration. Silent replacement can hide mistakes, which is one reason Spring Boot 2.1 disabled overriding by default.

Developers also forget that @Qualifier is often the clearer choice when there is no single sensible default bean. @Primary is best when one bean should usually win and the others are special-case alternatives.

Summary

  • Bean overriding and @Primary are different mechanisms.
  • Overriding replaces a bean definition with the same name, and Spring Boot 2.1 disables that by default.
  • '@Primary keeps all candidate beans and only chooses the default one for type-based injection.'
  • Use @Primary for injection preference, not for duplicate bean-name conflicts.
  • Prefer explicit configuration over blanket overriding when resolving container conflicts.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.