Вопрос проверяет понимание механизма внедрения зависимостей в Spring и способов разрешения конфликтов между бинами одного типа.
Если в контексте есть несколько бинов одного типа, Spring не знает, какой выбрать. Для управления выбором используются @Primary, @Qualifier и имена бинов. Также выбор может зависеть от профилей и условий. Неправильная настройка приводит к ошибкам старта приложения. Поэтому явное управление выбором бина — обязательная практика.
В Spring выбор бина происходит во время создания контекста и внедрения зависимостей.
Если в контексте есть:
два и более бина одного типа
и внедрение происходит по типу
Spring выбросит исключение:
NoUniqueBeanDefinitionException
Существует несколько основных механизмов.
Аннотация @Primary указывает бин по умолчанию:
@Primary
@Component
class MainService implements Service { }
Используется, когда:
один бин предпочтителен в большинстве случаев
@Qualifier позволяет явно указать нужный бин:
@Autowired
@Qualifier("fileStorage")
private Storage storage;
Это самый точный и безопасный способ.
Spring может внедрять бин по имени поля или параметра конструктора:
private Storage fileStorage;
Но этот подход менее явный и хуже читается.
Также можно управлять выбором через:
@Profile
@Conditional
@ConditionalOnProperty
Лучшие практики:
использовать конструкторную инъекцию
явно указывать @Qualifier
избегать неявных правил
Вывод: управление выбором бина — это осознанное устранение неоднозначности, а не надежда на поведение Spring по умолчанию.