Backend Development 7 min read

How to Precisely Choose a DAO Implementation in Spring: 8 Injection Techniques

This article explains eight practical ways to control which DAO implementation Spring injects, covering @Qualifier, bean naming, custom qualifiers, manual lookup, profile‑based beans, @Primary, and @Priority, with complete code examples for each method.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
How to Precisely Choose a DAO Implementation in Spring: 8 Injection Techniques

Environment: Spring 5.3.23

Problem: In a project two Service classes implement the same DAO interface; you need to explicitly specify which DAO implementation should be injected.

Spring provides several injection strategies such as @Qualifier , @Primary , custom qualifiers, profile‑based beans, and manual lookup. Below are eight concrete solutions.

Preparation

<code>static interface DAO {}

@Component
static class P1 implements DAO {}

@Component
static class P2 implements DAO {}

static class PersonService {
    @Resource
    private List&lt;DAO&gt; daos;
    @Override
    public String toString() {
        return "PersonService [daos=" + daos + "]";
    }
}

@Configuration
@ComponentScan(basePackages = {"com.pack"})
static class AppConfig {}

try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
    context.register(AppConfig.class);
    context.refresh();
    System.out.println(context.getBean(PersonService.class));
}
</code>

By default, PersonService.daos contains both P1 and P2 beans.

<code>PersonService [daos=[com.pack.P2@fa36558, com.pack.P1@672872e1]]</code>

Method 1: Use @Qualifier on the bean

<code>@Component
@Qualifier
static class P2 implements DAO {}

@Resource
@Qualifier
private List&lt;DAO&gt; daos;
</code>
<code>PersonService [daos=[com.pack.main.P2@2b4bac49]]</code>

Method 2: Use @Qualifier with bean name

<code>@Component
@Qualifier("p1")
static class P1 implements DAO {}

@Component
@Qualifier("p2")
static class P2 implements DAO {}

@Resource
@Qualifier("p1") // inject P1
private List&lt;DAO&gt; daos;
</code>
<code>PersonService [daos=[com.pack.P1@59252cb6]]</code>

Method 3: Custom qualifier annotation

<code>@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
@Qualifier
@interface MyLove {}

@Component
@MyLove
static class P2 implements DAO {}

@Resource
@MyLove
private List&lt;DAO&gt; daos;
</code>
<code>PersonService [daos=[com.pack.P2@7c9d8e2]]</code>

Method 4: Register a custom annotation

<code>@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
@interface PackInject {}

@Component
@PackInject
static class P2 implements DAO {}

@Resource
@PackInject
private List&lt;DAO&gt; daos;

// Register the custom qualifier so the container recognises it
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
    context.registerBean(CustomAutowireConfigurer.class, bd -> {
        Set<Class<?>> qualifierTypes = new HashSet<>();
        qualifierTypes.add(PackInject.class);
        bd.getPropertyValues().add("customQualifierTypes", qualifierTypes);
    });
}
</code>

Method 5: Manual lookup via ApplicationContextAware

<code>@Component
static class PersonService implements ApplicationContextAware {
    private DAO dao;
    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        this.dao = context.getBean("qualifierInjectMain4.P1", DAO.class);
    }
}
</code>

Method 6: Profile‑based bean registration

<code>static class AppConfig {
    @Bean
    @Profile("dev")
    public DAO p1() { return new P1(); }

    @Bean
    @Profile("prod")
    public DAO p2() { return new P2(); }
}

try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
    ConfigurableEnvironment env = context.getEnvironment();
    env.addActiveProfile("prod");
}
</code>

With the "prod" profile active, Spring injects the P2 bean.

Method 7: Use @Primary

<code>static class AppConfig {
    @Bean
    @Primary
    public DAO p1() { return new P1(); }

    @Bean
    public DAO p2() { return new P2(); }
}
</code>

The P1 bean becomes the default injection target.

Method 8: Use @Priority

<code>@Component
@Priority(-3)
static class P1 implements DAO {}

@Component
@Priority(-2)
static class P2 implements DAO {}
</code>

Beans with a lower priority value are chosen first.

All eight approaches allow you to control precisely which DAO implementation Spring injects into your service.

SpringCustom Annotationdependency 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.