@Resource vs @Autowired - PullRequest
       67

@Resource vs @Autowired

336 голосов
/ 04 ноября 2010

Какую аннотацию, @ Resource ( jsr250 ) или @ Autowired (для Spring) следует использовать в DI?

Я успешно использовал как в прошлом, @Resource(name="blah") и @Autowired @Qualifier("blah")

Мой инстинкт - придерживаться тега @Resource, так как он был ратифицирован людьми jsr.
У кого-нибудь есть сильные мысли по этому поводу?

Ответы [ 11 ]

467 голосов
/ 06 июня 2012

Оба @Autowired (или @Inject) и @Resource работают одинаково хорошо. Но есть концептуальная разница или разница в значении

  • @Resource означает получить мне известный ресурс по имени . Имя извлекается из имени аннотированного установщика или поля или из имени-параметра.
  • @Inject или @Autowired попытайтесь подключить подходящий другой компонент по типу .

Итак, в основном это два совершенно разных понятия. К сожалению, Spring-реализация @Resource имеет встроенный запасной вариант, который срабатывает при сбое разрешения по имени. В этом случае он возвращается к типу разрешения @Autowired. Хотя этот запасной вариант удобен, ИМХО он вызывает много путаницы, поскольку люди не знают о концептуальных различиях и склонны использовать @Resource для автопроводки на основе типов.

175 голосов
/ 04 ноября 2010

Весной до версии 3.0 не имеет значения, какая именно.

Весной 3.0 есть поддержка стандартной ( JSR-330 ) аннотации @javax.inject.Inject - используйте ее скомбинация @Qualifier.Обратите внимание, что пружина теперь также поддерживает метааннотацию @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 позволяет вам указать имя внедренного компонента
  • @Autowired позволяет пометить его как необязательное.
72 голосов
/ 04 ноября 2010

Основное отличие состоит в том, что @Autowired - это пружинная аннотация.Принимая во внимание, что @Resource определяется JSR-250, как вы указали сами.Таким образом, последний является частью Java, тогда как первый характерен для Spring.

Следовательно, вы правы, предлагая это в некотором смысле.Я обнаружил, что люди используют @Autowired с @Qualifier, потому что он более мощный.Переход от одной основы к другой считается маловероятным, если не мифом, особенно в случае с Spring.

63 голосов
/ 27 мая 2014

Я хотел бы подчеркнуть один комментарий от @ Жюль на этот ответ на этот вопрос. Комментарий содержит полезную ссылку: Spring Injection с @Resource, @Autowired и @ Inject . Я рекомендую вам прочитать его полностью, однако вот краткое изложение его полезности:

Как аннотации выбирают правильную реализацию?

@Autowired и @Inject

  1. Совпадения по типу
  2. Ограничения по классификаторам
  3. совпадений по имени

@Resource

  1. совпадений по имени
  2. Совпадения по типу
  3. Ограничения по классификаторам (игнорируется, если совпадение найдено по имени)

Какие аннотации (или комбинацию) я должен использовать для инъекции бобов?

  1. Явно назовите свой компонент [@Component ("beanName")]

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

Почему я не должен использовать @Qualifier?

Избегайте аннотаций @Qualifier, если вы не хотите создавать список похожих объектов. Например, вы можете пометить набор правил конкретной аннотацией @Qualifier. Такой подход упрощает внедрение группы классов правил в список, который можно использовать для обработки данных.

Инъекция бобов замедляет мою программу?

Сканирование определенных пакетов для компонентов [context:component-scan base-package="com.sourceallies.person"]. Хотя это приведет к большему количеству component-scan конфигураций, это уменьшит вероятность того, что вы добавите ненужные компоненты в свой контекст Spring.


Ссылка: Spring Injection с @Resource, @Autowired и @ Inject

38 голосов
/ 24 сентября 2013

Это то, что я получил из Spring 3.0.x Справочное руководство : -

Совет

Если вы хотите выразить инъекцию, основанную на аннотациях,name, в первую очередь не используйте @Autowired, даже если он технически способен ссылаться на имя компонента через значения @Qualifier.Вместо этого используйте аннотацию JSR-250 @Resource, которая семантически определена для идентификации конкретного целевого компонента по его уникальному имени, с объявленным типом, не относящимся к процессу сопоставления.

Как конкретное следствие этой семантикиРазница заключается в том, что bean-компоненты, которые сами определены как тип коллекции или карты, не могут быть внедрены через @Autowired, потому что сопоставление типов не применяется к ним должным образом.Используйте @Resource для таких bean-компонентов, ссылаясь на конкретную коллекцию или bean-компонент карты с уникальным именем.

@ Autowired применяется к полям, конструкторам и методам с несколькими аргументами, позволяя сужать аннотации квалификаторов на уровне параметров.Напротив, @Resource поддерживается только для полей и методов установки свойств бинов с одним аргументом.Как следствие, придерживайтесь квалификаторов, если ваша цель внедрения - конструктор или метод с несколькими аргументами.

20 голосов
/ 26 марта 2015

@ Autowired + @Qualifier будет работать только с пружинным DI, если вы хотите использовать какой-то другой DI в будущем. @Resource - хороший вариант.

Другое отличие, которое я нашел очень существенным, - @Qualifier не поддерживаетдинамическое связывание bean, поскольку @Qualifier не поддерживает заполнитель, в то время как @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;

, которая не обеспечивает заполнитель, в то время как с @Resource вы можете поместить заполнитель и использовать файл свойств для внедрения конкретной дочерней реализации, например

@Resource(name="${service.name}")
Parent object;  

где имя файла service.name установлено в файле свойств как

#service.name=actualService
 service.name=stubbedService

Надеюсь, что это кому-нибудь поможет:)

16 голосов
/ 04 ноября 2010

Оба они одинаково хороши.Преимущество использования Resource в будущем, если вы захотите использовать другую инфраструктуру DI, отличную от Spring, изменения в вашем коде будут намного проще.При использовании Autowired ваш код тесно связан с пружинами DI.

8 голосов
/ 05 октября 2018

Когда вы анализируете критически из базовых классов этих двух аннотаций. Вы поймете следующие различия.

@Autowired использует AutowiredAnnotationBeanPostProcessor для внедрения зависимостей.
@Resource использует CommonAnnotationBeanPostProcessorдля внедрения зависимостей.

Даже если они используют разные классы постпроцессора, они все ведут себя почти одинаково.Различия критически заключаются в их путях выполнения, которые я выделил ниже.

@Autowired / @Inject

1. Соответствия по типу
2. Ограничения по классификаторам
3. Соответствия по имени

@Resource

1. Сопоставления по имени
2. Сопоставления по типу
3. Ограничения по классификаторам (игнорируется, если совпадение найдено по имени)

4 голосов
/ 20 июня 2017

С помощью @Resource вы можете делать бин с самоинъекцией, это может понадобиться для запуска всей дополнительной логики, добавляемой постпроцессорами бинов, например, транзакций или безопасности.

С Spring 4.3+ @Autowired также способен на это.

2 голосов
/ 07 марта 2014

@Resource часто используется высокоуровневыми объектами, определенными через JNDI. @Autowired или @Inject будут использоваться более распространенными бобами.

Насколько я знаю, это не спецификация и даже не соглашение. Это более логичный способ, которым стандартный код будет использовать эти аннотации.

...