@Resource vs @Autowired



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



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



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

У кого есть сильные мысли по этому поводу?

807   11  

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 для автопроводки на основе типов.

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

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

Я хотел бы подчеркнуть один комментарий @Jules on ответ на этот вопрос. Комментарий приносит полезную ссылку: впрыска Весны с @ресурсом, @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 конфигурации это уменьшает вероятность того, что вы добавите ненужные компоненты в свой весенний контекст.


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

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

Совет

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

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

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

@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 устанавливается в файле свойств как

#service.name=actualService
 service.name=stubbedService

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

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

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

С Весны 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.Ограничивает Квалификаторами (игнорируется, если совпадение найдено по имени)

Comments

    Ничего не найдено.