@Resource vs @Autowired
Какую аннотацию, @Resource (jsr250) или @Autowired (Spring-specific) следует использовать в DI?
Я успешно использовал оба в прошлом, @Resource(name="blah")
и @Autowired @Qualifier("blah")
Мой инстинкт заключается в том, чтобы придерживаться тега @Resource
поскольку он был ратифицирован людьми jsr.
У кого есть сильные мысли по этому поводу?
Ответы
Ответ 1
В spring pre-3.0 не имеет значения, какой из них.
В spring 3.0 поддерживается стандартная (JSR-330) аннотация @javax.inject.Inject
- используйте ее с комбинацией @Qualifier
. Обратите внимание, что spring теперь также поддерживает мета-аннотацию @javax.inject.Qualifier
:
@Qualifier
@Retention(RUNTIME)
public @interface YourQualifier {}
Итак, вы можете иметь
<bean class="com.pkg.SomeBean">
<qualifier type="YourQualifier"/>
</bean>
или
@YourQualifier
@Component
public class SomeBean implements Foo { .. }
И затем:
@Inject @YourQualifier private Foo foo;
Это уменьшает использование строковых имен, которые могут быть написаны с ошибками и их сложнее поддерживать.
Что касается исходного вопроса: оба без указания каких-либо атрибутов аннотации выполняют инъекцию по типу. Разница заключается в следующем:
-
@Resource
позволяет указать имя введенного bean
-
@Autowired
позволяет пометить его как необязательный.
Ответ 2
Оба @Autowired
(или @Inject
) и @Resource
работают одинаково хорошо. Но есть концептуальная разница или разница в значении
-
@Resource
означает получить мне известный ресурс по имени. Имя извлекается из имени аннотированного сеттера или поля, или оно берется из имени-параметра.
-
@Inject
или @Autowired
попробуйте подключиться к подходящему другому компоненту по типу.
Итак, в основном это два совершенно разных понятия. К сожалению, Spring -Implementation @Resource
имеет встроенный резерв, который срабатывает, когда сбой разрешения по умолчанию терпит неудачу. В этом случае он возвращается к типу @Autowired
-kind. Хотя это резервное копирование удобно, ИМХО вызывает много путаницы, потому что люди не знают концептуальной разницы и склонны использовать @Resource
для автопомощи на основе типов.
Ответ 3
Основное отличие: @Autowired
- аннотация spring. В то время как @Resource
определяется JSR-250, как вы указали сами. Таким образом, последний является частью Java, тогда как первый имеет значение spring.
Следовательно, вы правы, предлагая это в некотором смысле. Я нашел, что люди используют @Autowired
с @Qualifier
, потому что он более мощный. Переход от некоторой структуры к какой-то другой считается очень маловероятным, если не мифом, особенно в случае Spring.
Ответ 4
Я хотел бы подчеркнуть один комментарий от @Jules на этот ответ на этот вопрос. Комментарий содержит полезную ссылку: Spring Инъекция с @Resource, @Autowired и @Inject. Я рекомендую вам прочитать его целиком, но вот краткое изложение его полезности:
Как аннотации выбирают правильную реализацию?
@Autowired
и @Inject
- Соответствует типу
- Ограничения по квалификаторам
- Соответствует названию
@Resource
- Соответствует названию
- Соответствует типу
- Ограничивает квалификаторы (игнорируется, если совпадение найдено по имени)
Какие аннотации (или комбинации) следует использовать для ввода моего beans?
Почему я не должен использовать @Qualifier
?
Избегайте аннотаций @Qualifier
, если вы не хотите создавать список похожих beans. Например, вы можете пометить набор правил с помощью специальной аннотации @Qualifier
. Этот подход упрощает введение группы классов правил в список, который может использоваться для обработки данных.
Выполняет ли bean инъекцию моей программы?
Сканировать определенные пакеты для компонентов [context:component-scan base-package="com.sourceallies.person"]
. Хотя это приведет к более component-scan
конфигурациям, это уменьшит вероятность того, что вы добавите ненужные компоненты в контекст Spring.
Ссылка: Spring Инъекция с @Resource, @Autowired и @Inject
Ответ 5
Это то, что я получил из справочного руководства Spring 3.0.x: -
Совет
Если вы намереваетесь выразить инъекцию, вызванную аннотациями, по имени, do не в первую очередь использовать @Autowired, даже если технически ссылаясь на имя bean через значения @Qualifier. Вместо этого используйте JSR-250 @Resource аннотация, которая семантически определена для идентифицировать конкретный целевой компонент по его уникальному имени, объявленный тип не имеет отношения к процессу сопоставления.
Как конкретное следствие этой семантической разницы, beans, которые сами определяемые как тип коллекции или карты, не могут быть введены через @Autowired, потому что соответствие типов не применяется должным образом им. Используйте @Resource для такого beans, ссылаясь на конкретный коллекции или карты bean по уникальному имени.
@Autowired применяется к полям, конструкторам и нескольким аргументам методов, позволяющих сузить через аннотации классификатора на уровень параметра. В отличие от этого, @Resource поддерживается только для полей и bean методы настройки свойств с одним аргументом. Как последствия, придерживаться квалификаторов, если ваша цель инъекции конструктор или метод с несколькими аргументами.
Ответ 6
@Autowired + @Qualifier будет работать только с spring DI, если вы хотите использовать какой-либо другой DI в будущем @Resource - хороший вариант.
Другая разница, которую я нашел очень значимой, - @Qualifier не поддерживает динамическую проводку bean, поскольку @Qualifier не поддерживает placeholder, в то время как @Resource делает это очень хорошо.
Например:
если у вас есть интерфейс с несколькими реализациями, подобными этому
interface parent {
}
@Service("actualService")
class ActualService implements parent{
}
@Service("stubbedService")
class SubbedService implements parent{
}
с @Autowired и @Qualifier вам нужно установить конкретную реализацию ребенка
как
@Autowired
@Qualifier("actualService") or
@Qualifier("stubbedService")
Parent object;
который не предоставляет placeholder, а с помощью @Resource вы можете помещать placeholder и использовать файл свойства для инъекции конкретной реализации ребенка, например
@Resource(name="${service.name}")
Parent object;
где service.name устанавливается в файле свойств как
#service.name=actualService
service.name=stubbedService
Надеюсь, что это поможет кому-то:)
Ответ 7
Оба они одинаково хороши. Преимущество использования ресурса в будущем, если вы хотите другой каркас DI, кроме spring, ваши изменения кода будут намного проще. Использование Autowired вашего кода тесно связано с пружинами DI.
Ответ 8
С помощью @Resource
вы можете сделать bean самозавершение, оно может потребоваться для запуска всей дополнительной логики, добавленной post-процессорами bean, такими как транзакционные или связанные с безопасностью вещи.
С Spring 4.3+ @Autowired
также можно это сделать.
Ответ 9
@Resource
часто используется объектами высокого уровня, определенными через JNDI. @Autowired
или @Inject
будет использоваться более распространенным beans.
Насколько я знаю, это не спецификация и даже соглашение. Это более логичный способ использования стандартного кода этих аннотаций.
Ответ 10
В качестве примечания здесь:
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext
и SpringBeanAutowiringSupport.processInjectionBasedOnServletContext
НЕ работает с аннотацией @Resource
. Итак, есть разница.