@Resource vs @Autowired
222193 просмотра
11 ответа
Какую аннотацию, @Resource ( jsr250 ) или @Autowired (для Spring) следует использовать в DI?
Я успешно использовал как в прошлом, так @Resource(name="blah")
и@Autowired @Qualifier("blah")
Мой инстинкт состоит в том, чтобы придерживаться @Resource
тега, так как он был утвержден людьми jsr.
У кого-нибудь есть сильные мысли по этому поводу?
Ответы (11)
185 плюса
Весной до 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
позволяет пометить его как необязательный.
483 плюса
И @Autowired
(или @Inject
) и @Resource
одинаково хорошо работают. Но есть концептуальная разница или разница в значении
@Resource
значит достань мне известный ресурс по имени . Имя извлекается из имени аннотированного установщика или поля или берется из name-Parameter.@Inject
или@Autowired
попробуйте подключить подходящий другой компонент по типу .
Итак, в основном это две совершенно разные концепции. К сожалению, в Spring -ализации @Resource
есть встроенный запасной вариант, который срабатывает при сбое разрешения по имени. В этом случае он возвращается к @Autowired
разрешению -kind по типу. Хотя этот запасной вариант удобен, ИМХО он вызывает много путаницы, поскольку люди не знают о концептуальных различиях и склонны использовать их @Resource
для автопроводки на основе типов.
73 плюса
Основное отличие состоит в том, @Autowired
что это весенняя аннотация. Принимая во внимание, @Resource
что определено JSR-250, как вы указали сами. Таким образом, последний является частью Java, тогда как первый характерен для Spring.
Следовательно, вы правы, предлагая это в некотором смысле. Я нашел, что люди используют @Autowired
с, @Qualifier
потому что это более сильно. Переход от одного каркаса к другому считается маловероятным, если не мифом, особенно в случае весны.
64 плюса
Я хотел бы подчеркнуть один комментарий @Jules на этот ответ на этот вопрос. Комментарий содержит полезную ссылку: Spring Injection с @Resource, @Autowired и @Inject . Я призываю вас прочитать его полностью, однако вот краткое изложение его полезности:
Как аннотации выбирают правильную реализацию?
@Autowired
а также @Inject
- Совпадения по типу
- Ограничения по классификаторам
- Матчи по имени
@Resource
- Матчи по имени
- Совпадения по типу
- Ограничения по квалификаторам (игнорируется, если совпадение найдено по имени)
Какие аннотации (или комбинацию) я должен использовать для инъекции моих бобов?
Явно назовите свой компонент [@Component ("beanName")]
Использовать
@Resource
сname
атрибутом [@Resource (name = "beanName")]
Почему я не должен использовать @Qualifier
?
Избегайте @Qualifier
аннотаций, если вы не хотите создавать список похожих бинов. Например, вы можете пометить набор правил конкретной @Qualifier
аннотацией. Такой подход упрощает внедрение группы классов правил в список, который можно использовать для обработки данных.
Инъекция бобов замедляет мою программу?
Сканирование определенных пакетов для компонентов [context:component-scan base-package="com.sourceallies.person"]
. Хотя это приведет к большему количеству component-scan
конфигураций, это уменьшит вероятность того, что вы добавите ненужные компоненты в свой контекст Spring.
Ссылка: Spring Injection с помощью @Resource, @Autowired и @Inject
Автор: Stephan Размещён: 27.05.2014 10:5638 плюса
Вот что я получил из справочного руководства Spring 3.0.x :
Автор: Kartik Размещён: 24.09.2013 09:26Чаевые
Если вы намерены выражать внедрение, основанное на аннотациях, по имени, не используйте в первую очередь @Autowired, даже если он технически способен ссылаться на имя компонента с помощью значений @Qualifier. Вместо этого используйте аннотацию JSR-250 @Resource, которая семантически определена для идентификации конкретного целевого компонента по его уникальному имени, причем объявленный тип не имеет значения для процесса сопоставления.
Как конкретное следствие этого семантического различия, bean-компоненты, которые сами определены как тип коллекции или карты, не могут быть внедрены через @Autowired, потому что сопоставление типов не применимо к ним должным образом. Используйте @Resource для таких bean-компонентов, ссылаясь на конкретную коллекцию или bean-компонент карты с уникальным именем.
@Autowired применяется к полям, конструкторам и методам с несколькими аргументами, что позволяет сужать аннотации квалификаторов на уровне параметров. Напротив, @Resource поддерживается только для полей и методов установки свойств бинов с одним аргументом. Как следствие, придерживайтесь квалификаторов, если ваша цель внедрения - конструктор или метод с несколькими аргументами.
21 плюса
@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
Надеюсь, что это помогает кому-то :)
Автор: Ali Размещён: 26.03.2015 03:5516 плюса
Оба они одинаково хороши. Преимущество использования Resource в будущем, если вы захотите использовать другую инфраструктуру DI, отличную от Spring, изменения в вашем коде будут намного проще. При использовании Autowired ваш код тесно связан с пружинами DI.
Автор: Teja Kantamneni Размещён: 04.11.2010 02:5910 плюса
Когда вы проанализируете критически из базовых классов этих двух аннотаций. Вы поймете следующие различия.
@Autowired
использует AutowiredAnnotationBeanPostProcessor
для внедрения зависимостей.
@Resource
использует CommonAnnotationBeanPostProcessor
для внедрения зависимостей.
Несмотря на то, что они используют разные классы постпроцессора, они ведут себя почти одинаково. Различия критически заключаются в путях их выполнения, которые я выделил ниже.
@Autowired / @Inject
1. Соответствия по типу
2. Ограничения по
классификатору 3. Соответствия по имени
@Resource
1. Сопоставления по имени
2. Сопоставления по типу
3. Ограничения по квалификаторам (игнорируется, если совпадение найдено по имени)
5 плюса
Если @Resource
вы можете делать бин с самоинъекцией, это может понадобиться для запуска всей дополнительной логики, добавляемой постпроцессорами бинов, такими как транзакции или средства безопасности.
С помощью Spring 4.3+ @Autowired
это тоже возможно.
2 плюса
@Resource
часто используется высокоуровневыми объектами, определенными через JNDI. @Autowired
или @Inject
будет использоваться более распространенными бобами.
Насколько я знаю, это не спецификация и даже не соглашение. Это более логичный способ, которым стандартный код будет использовать эти аннотации.
Автор: Nicolas Zozol Размещён: 07.03.2014 06:060 плюса
Как примечание здесь:
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext
и SpringBeanAutowiringSupport.processInjectionBasedOnServletContext
не работает с @Resource
аннотацией. Итак, есть разница.
Вопросы из категории :
- java В чем разница между int и Integer в Java и C #?
- java Как я могу определить IP моего маршрутизатора / шлюза в Java?
- java Каков наилучший способ проверки XML-файла по сравнению с XSD-файлом?
- java Как округлить результат целочисленного деления?
- spring Получение Spring Application Context
- spring BeanFactory против ApplicationContext
- spring Тип безопасности: непроверенный актерский состав
- spring Код модульного тестирования, отправляющий сообщения JMS
- dependency-injection Что такое внедрение зависимостей?
- dependency-injection Dependency Injection vs Factory Pattern
- dependency-injection Каковы минимальные зависимости Spring для внедрения зависимостей?
- dependency-injection Автоматическая фабрика с Common.Logging и Autofac?
- annotations Когда вы используете аннотацию @Override в Java и почему?
- annotations Должны ли мы @Override реализации метода интерфейса?
- annotations Сканирование аннотаций Java во время выполнения
- annotations Создать экземпляр аннотации со значениями по умолчанию в Java
- autowired Как работает электропроводка весной?
- autowired Как работает аннотация Spring @Autowired?
- autowired @Resource vs @Autowired
- autowired Spring @Autowired не работает