В чем отличие между @Autowired, @Inject и @Resource в Spring
Что проверяют
Понимаете ли вы, как Spring выбирает бин, когда кандидатов несколько, и откуда берутся эти три аннотации. Следом обычно спрашивают, что будет при двух бинах одного типа или почему рекомендуют внедрение через конструктор.
Как отвечать
@Autowired: аннотация Spring, ищет бин по типу.@Qualifierсужает список кандидатов, из оставшихся побеждает@Primary, в последнюю очередь Spring сверяет имя поля или параметра с именем бина. Есть атрибутrequired(по умолчаниюtrue), необязательную зависимость удобнее объявить какOptional<T>илиObjectProvider<T>;@Inject: стандарт JSR-330, сейчас пакетjakarta.inject, нужна зависимостьjakarta.inject-api. В Spring её обрабатывает тот жеAutowiredAnnotationBeanPostProcessor, и ведёт она себя как@Autowired, только безrequired. Для уточнения есть@Named, при этом спринговый@Qualifierрядом с ней тоже работает;@Resource: стандарт JSR-250, сейчасjakarta.annotation.Resource. Ищет сначала по имени: из атрибутаname, иначе по имени поля или свойства сеттера. Если имя не задано явно и бина с именем поля нет, Spring откатывается к поиску по типу. Ставится на поле или сеттер, на конструктор нельзя. Обрабатывает еёCommonAnnotationBeanPostProcessor.
На практике все три чаще заменяет внедрение через конструктор. С Spring 4.3 при единственном конструкторе аннотация не нужна, зависимости видны в сигнатуре, поля можно сделать final, а класс легко создать в тесте без контекста. @Inject выбирают, когда код не должен зависеть от Spring, @Resource там, где бин важно брать именно по имени.
Где спотыкаются
Говорят, что @Autowired работает строго по типу. При нескольких кандидатах без @Primary и @Qualifier Spring всё равно попробует имя, и переименование поля неожиданно меняет, какой бин внедрён.
Утверждают, что @Resource не относится к DI Spring и годится только для JNDI-ресурсов. Spring полноценно обрабатывает её для обычных бинов.
Ставят @Autowired на поле и обращаются к нему в конструкторе. Поля заполняются после создания объекта, поэтому в конструкторе там ещё null, и это ещё один довод за внедрение через конструктор.