Вопрос проверяет понимание аннотации @Primary в Spring, которая используется для разрешения неоднозначностей при внедрении зависимостей, когда существует несколько бинов одного типа.
В Spring Framework, когда контейнер IoC (Inversion of Control) сталкивается с ситуацией, где несколько бинов реализуют один и тот же тип (интерфейс или класс), возникает неоднозначность при автоматическом связывании зависимостей через @Autowired. Аннотация @Primary — это один из способов указать контейнеру, какой бин следует выбирать по умолчанию в таких случаях.
Вы помечаете один из бинов аннотацией @Primary (обычно на уровне определения бина в конфигурационном классе с @Bean или на самом классе компонента с @Component). Когда Spring выполняет инъекцию зависимости по типу и находит несколько подходящих кандидатов, он отдаёт предпочтение тому, который помечен как @Primary. Если @Primary отсутствует, потребуется использовать @Qualifier для явного указания имени бина, иначе Spring выбросит исключение NoUniqueBeanDefinitionException.
Предположим, у нас есть интерфейс MessageService и две его реализации. Мы хотим, чтобы EmailService использовался по умолчанию.
public interface MessageService {
String send(String message);
}
@Component
@Primary // Этот бин будет выбран по умолчанию
public class EmailService implements MessageService {
public String send(String message) {
return "Sent via email: " + message;
}
}
@Component
public class SmsService implements MessageService {
public String send(String message) {
return "Sent via SMS: " + message;
}
}
@Component
public class NotificationService {
private final MessageService messageService;
@Autowired
public NotificationService(MessageService messageService) {
// Будет внедрён EmailService, так как он @Primary
this.messageService = messageService;
}
public void notifyUser(String msg) {
System.out.println(messageService.send(msg));
}
}@MockBean в Spring Boot тестах часто помечается как @Primary).Вывод: Используйте @Primary, когда вам нужно задать бин по умолчанию среди нескольких однотипных бинов, чтобы упростить конфигурацию и избежать необходимости явного указания @Qualifier в большинстве мест инъекции. Это особенно полезно в больших приложениях с множеством альтернативных реализаций.