Что произойдет при внедрении главного робота, если есть несколько кандидатов на внедрение?
Что проверяют
Вопрос про внедрение зависимости, когда по типу подходит несколько бинов, формулировка искажена расшифровкой. Смотрят, знаете ли вы алгоритм выбора в Spring и умеете ли снимать неоднозначность, не ломая остальной контекст.
Как отвечать
Контейнер ищет кандидатов по типу. Один кандидат внедряется сразу. Если ни одного, будет NoSuchBeanDefinitionException. Если несколько, Spring пробует сузить выбор по очереди: сначала бин, помеченный @Primary, затем совпадение с @Qualifier, затем совпадение имени бина с именем поля или параметра конструктора. Не помогло ничего, приложение падает при старте с NoUniqueBeanDefinitionException, и это хорошая новость: ошибка видна сразу, а не на первом запросе в проде.
@Bean @Primary PaymentGateway card() { ... }
@Bean PaymentGateway sbp() { ... }
@Service
class Checkout {
Checkout(@Qualifier("sbp") PaymentGateway gateway) { ... }
}Стоит добавить варианты, когда кандидатов много осознанно: внедрение List<PaymentGateway> отдаёт все реализации, Map<String, PaymentGateway> отдаёт их же с именами бинов в ключах, порядок задаётся через @Order. Для необязательной зависимости есть Optional<T> и ObjectProvider<T>.
Где спотыкаются
Вешают @Primary на две реализации сразу и получают ту же самую ошибку, только с другим текстом. Главный кандидат по определению один, а для остального есть квалификаторы.
Второе: полагаются на совпадение имени параметра конструктора. Имена параметров попадают в класс только при компиляции с ключом -parameters, и сборка без него поднимается на машине разработчика, но валится на сервере, где профиль сборки другой.
Третье: разбираются с симптомом вместо причины. Часто второй кандидат появился случайно: одна и та же реализация объявлена и через @Component, и через @Bean в конфигурации, либо автоконфигурация добавила свою. Развешивать @Qualifier по всем точкам внедрения в этом случае значит закрепить лишний бин.