@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?

  • Явным образом назовите ваш компонент [@Component ( "beanName" )]

  • Используйте @Resource с атрибутом name [@Resource (name= "beanName" )]

Почему я не должен использовать @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. Итак, есть разница.