DEV Community

Willian Ferreira Moya
Willian Ferreira Moya

Posted on • Originally published at springmasteryhub.com

Understanding @Primary in Spring

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");
    }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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!

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

When you call the controller:

curl http://localhost:8080/new-greetings
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)