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

static interface DAO {}

@Component
static class P1 implements DAO {}

@Component
static class P2 implements DAO {}

static class PersonService {
    @Resource
    private List<DAO> 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));
}

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

PersonService [daos=[com.pack.P2@fa36558, com.pack.P1@672872e1]]

Method 1: Use @Qualifier on the bean

@Component
@Qualifier
static class P2 implements DAO {}

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

Method 2: Use @Qualifier with bean name

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

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

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

Method 3: Custom qualifier annotation

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

@Component
@MyLove
static class P2 implements DAO {}

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

Method 4: Register a custom annotation

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

@Component
@PackInject
static class P2 implements DAO {}

@Resource
@PackInject
private List<DAO> 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);
    });
}

Method 5: Manual lookup via ApplicationContextAware

@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);
    }
}

Method 6: Profile‑based bean registration

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");
}

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

Method 7: Use @Primary

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

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

The P1 bean becomes the default injection target.

Method 8: Use @Priority

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

@Component
@Priority(-2)
static class P2 implements DAO {}

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

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

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.