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.
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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
