If you read my post about the @Qualifier
annotation, you have noticed that defining two beans of the same type can be a challenge. By distinguishing it with a qualifier name, @Qualifier
helps Spring determine which bean to inject.
The @Primary
annotation will help Spring decide which of those same types of beans it should pick primarily.
For the bean annotated with the @Primary
annotation, the @Qualifier
will not be necessary. It is only required for the other bean.
Example 1: Using @primary and @Qualifier in Spring
Let’s see the example in practice:
public interface GreetingService {
String greet();
}
@Service
@Primary
public class EnglishGreetingService implements GreetingService {
@Override
public String greet() {
return "Hello!";
}
}
@Service("spanishGreetingService")
public class SpanishGreetingService implements GreetingService {
@Override
public String greet() {
return "Hola!";
}
}
@RestController
@RequestMapping("/greet")
public class GreetingController {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(GreetingController.class);
@Autowired
private GreetingService greetingService;
@Autowired
@Qualifier("spanishGreetingService")
private GreetingService spanishGreetingService;
@GetMapping
public ResponseEntity<String> printGreetings() {
log.info(greetingService.greet());
log.info(spanishGreetingService.greet());
return ResponseEntity.ok("greetings");
}
}
You won’t need to use the @Qualifier
on the bean you defined as @Primary
When you call this controller with this curl:
curl http://localhost:8080/greet
You are going to see in the logs that the primary one was automatically set:
2024-06-20T21:08:53.884-03:00 INFO 1868 --- [nio-8080-exec-1] c.s.mastery.primary.GreetingController : Hello!
2024-06-20T21:08:53.884-03:00 INFO 1868 --- [nio-8080-exec-1] c.s.mastery.primary.GreetingController : Hola!
Example 2: Using @primary at the Configuration Level
Another example is when you need to use the bean at the configuration level, so it will not be possible to use the @Qualifier
to identify which bean Spring should inject.
@Configuration
public class AppPrimaryConfig {
@Bean
@Primary
public ConfigGreetingService portugueseGreetings() {
return new PortugueseGreetings();
}
@Bean("italianGreetings")
public ConfigGreetingService italianGreetings() {
return new ItalianGreetings();
}
}
@RestController
@RequestMapping("/new-greetings")
public class NewGreetingController {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(GreetingController.class);
@Autowired
private ConfigGreetingService greetingService;
@Autowired
@Qualifier("italianGreetings")
private ConfigGreetingService italianGreetings;
@GetMapping
public ResponseEntity<String> printGreetings() {
log.info(greetingService.greet());
log.info(italianGreetings.greet());
return ResponseEntity.ok("greetings");
}
}
When you call the controller:
curl http://localhost:8080/new-greetings
You should see:
2024-06-20T21:10:17.517-03:00 INFO 8768 --- [nio-8080-exec-1] c.s.mastery.primary.GreetingController : Ola
2024-06-20T21:10:17.517-03:00 INFO 8768 --- [nio-8080-exec-1] c.s.mastery.primary.GreetingController : Ciao
Conclusion
In this blog post, you learned about the @Primary
annotation and its use cases.
If you like this topic, make sure to follow me. In the following days, I’ll be explaining more about Spring annotations! Stay tuned!
Follow me!
Top comments (0)