Ответ
Spring выбросит исключение NoUniqueBeanDefinitionException при попытке инжекции по типу (например, через @Autowired), так как контейнер не сможет однозначно определить, какой бин использовать.
Способы разрешения неоднозначности:
-
Аннотация
@Primary— помечает один бин как предпочтительный.@Configuration public class AppConfig { @Bean @Primary // Этот бин будет выбран по умолчанию public MyService primaryService() { return new PrimaryServiceImpl(); } @Bean public MyService secondaryService() { return new SecondaryServiceImpl(); } } -
Аннотация
@Qualifier— явное указание имени конкретного бина.@Component public class ClientComponent { @Autowired @Qualifier("secondaryService") // Указываем конкретное имя бина private MyService service; } -
Совпадение имени поля с именем бина (работает в некоторых случаях, но ненадежно).
@Autowired private MyService secondaryService; // Может инжектиться бин с именем "secondaryService" -
Инжекция всех бинов этого типа в коллекцию.
@Autowired private List<MyService> allServices; // Инжектит оба бина
Рекомендация: Используйте @Qualifier для явного и понятного выбора нужной реализации.
Ответ 18+ 🔞
А, ну это же классика, блядь! Весна, такая вся из себя умная, а тут — бац, и не может выбрать, какую хуйню тебе впендюрить. Представь: сидит контейнер, чешет репу, а перед ним два одинаковых бина, как близнецы-пиздюки, и он такой: «Ну ёпта, а какую же, блядь, из них сувать-то?» И швыряет тебе в рожу NoUniqueBeanDefinitionException. Красота, да?
Но не ссы, есть способы этого долбоёба направить на путь истинный.
Варианты, как выкрутиться:
-
@Primary— типа главный пацан.
Вешаешь эту приблуду на одного из кандидатов, и Spring сразу понимает: «А, ну этот, значит, по умолчанию, остальные — так, запасные хуи».@Configuration public class AppConfig { @Bean @Primary // Этот чувак теперь главный, его и будут совать везде, если не указано иное public MyService primaryService() { return new PrimaryServiceImpl(); } @Bean public MyService secondaryService() { return new SecondaryServiceImpl(); } } -
@Qualifier— точный прицел по имени.
Тут уже ты сам, как снайпер, указываешь, какую именно реализацию тебе подсунуть. Никаких недопониманий, блядь.@Component public class ClientComponent { @Autowired @Qualifier("secondaryService") // Чётко говоришь: «Давай ту, что secondaryService, а не какую-то левую!» private MyService service; } -
Совпадение имени поля — автопилот, который может и в дерево въебать.
Иногда, если повезёт, Spring может догадаться, если имя поля совпадёт с именем бина. Но надеяться на это — всё равно что играть в русскую рулетку, ёпта.@Autowired private MyService secondaryService; // Может, блядь, подтянет бин с именем "secondaryService", а может, и нет — как карта ляжет. -
Забрать всех скопом — автобус для бинов.
А можно не париться и взять всех кандидатов разом, запихнуть в коллекцию — и пусть там сами разбираются.@Autowired private List<MyService> allServices; // Инжектит все бины типа MyService — и делов-то!
Что в итоге?
Если хочешь спать спокойно и не гадать, что тебе впендюрят — юзай @Qualifier. Чётко, ясно, без этих вот «авось пронесёт». А то потом сидишь и думаешь: «И какого хуя тут primaryService оказался, когда мне secondary был нужен?»