Backend Development 8 min read

Mastering Spring Boot Bean Selection: 6 Ways to Choose the Right Implementation

This tutorial walks through six practical techniques—@Qualifier, @Primary, @Profile, collection injection, @Priority, and custom @Conditional—to control which implementation of a Spring Boot interface is autowired, complete with code examples and usage tips.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Mastering Spring Boot Bean Selection: 6 Ways to Choose the Right Implementation

In this article we explore how to select the correct implementation class for injection when an interface has multiple implementations in Spring Boot.

When Spring cannot decide which bean to inject, it throws the error “required a single bean but found X”, indicating ambiguity.

1. Use @Qualifier

Assign a custom qualifier name to a bean and reference it during injection.

<code>@Repository
@Qualifier("mysqlDAO-1")
public class MySQLDAO implements DAO<User> {}

@Repository
public class OracleDAO implements DAO<User> {}

@Component
public class CompDAO {
    private final DAO dao1;
    private final DAO dao2;
    public CompDAO(@Qualifier("mysqlDAO-1") DAO dao1, DAO oracleDAO) {
        this.dao1 = dao1;
        this.dao2 = oracleDAO;
    }
}
</code>

2. Use @Primary

Mark one implementation as primary so Spring picks it when no qualifier is specified.

<code>@Repository
@Primary
public class OracleDAO implements DAO<User> {}
</code>

If other implementations are needed, retrieve them manually via ApplicationContext#getBean .

3. Use @Profile

Activate beans only under specific Spring profiles (e.g., dev or prod ).

<code>@Repository
@Profile("dev")
public class MySQLDAO implements DAO<User> {}

@Repository
@Profile("prod")
public class OracleDAO implements DAO<User> {}
</code>

The active profile is controlled by the spring.profiles.active property.

4. Inject All Implementations into a Collection

Spring can inject all beans of a type into a List , Set , Map , or array.

<code>@Component
public class CompDAO {
    private final List<DAO> daos;
    public CompDAO(List<DAO> daos) { this.daos = daos; }
}
</code>
<code>@Component
public class CompDAO {
    private final Map<String, DAO> daos;
    public CompDAO(Map<String, DAO> daos) { this.daos = daos; }
    public void use() {
        MySQLDAO mdao = (MySQLDAO) this.daos.get("mySQLDAO");
        OracleDAO odao = (OracleDAO) this.daos.get("oracleDAO");
        // TODO
    }
}
</code>

When using a Map , Spring ignores @Qualifier and profile annotations for beans that do not match the current profile.

5. Use @Priority

Assign an integer priority (lower value = higher priority) to beans; the highest‑priority bean is chosen for injection.

<code>@Repository
@Priority(2)
public class OracleDAO implements DAO<Date> {}

@Repository
@Priority(1)
public class MySQLDAO implements DAO<Date> {}
</code>

In this example, MySQLDAO will be injected because it has the smallest priority value.

6. Custom @Conditional

Create a class implementing Condition and use @Conditional to activate a bean only when custom logic returns true.

<code>public class PackCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return "mysql".equalsIgnoreCase(context.getEnvironment().getProperty("pack.active"));
    }
}
</code>
<code>@Repository
@Conditional(PackCondition.class)
public class MySQLDAO implements DAO<User> {}
</code>

Only when the property pack.active is set to mysql will MySQLDAO be created.

JavaSpring BootDependency InjectionQualifierprofilePrimary
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.