@ Resource vs @Autowired

которые Примечания @Resource (jsr250) или @Autowired (Spring-specific) должен ли я использовать в DI?

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

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

11 ответов


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

весной 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 позволяет указать имя вводимого компонента
  • @Autowired позволяет отметить его как необязательный.

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

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

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


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

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

Я хотел бы подчеркнуть один комментарий @Jules on ответ на этот вопрос. Комментарий приносит полезную ссылку:впрыска Весны с @ ресурсом, @Autowired и @впрыскивает. Я призываю вас прочитать его полностью, однако вот краткое резюме его полезности:

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

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


ссылки: впрыска Весны с @ ресурсом, @Autowired и @впрыскивает


Это то, что я получил от Весна 3.0.х справочное руководство :-

Совет

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

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

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


@Autowired + @Qualifier будет работать только с spring 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=actualService
 service.name=stubbedService

надеюсь, что кто-то поможет:)


оба они одинаково хороши. Преимущество использования ресурса в будущем, если вы хотите другую структуру DI, отличную от spring, ваши изменения кода будут намного проще. Использование Autowired ваш код тесно связан с springs DI.


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

С Весны 4.3+ @Autowired также способен это сделать.


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

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


как Примечание здесь: SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext и SpringBeanAutowiringSupport.processInjectionBasedOnServletContext НЕ работы с @Resource Примечание. Так что есть разница.


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

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

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

@Autowired / @Inject

1.Матчи Тип
2.Ограничивает Квалификаторами
3.Спички по имени

@Resource

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