В чем разница между @Inject и @Autowired в Spring Framework? Какой использовать при каких условиях?


695

Я просматриваю некоторые блоги на SpringSource и в одном из блогов, которые использует автор, @Injectи я полагаю, что он также может использовать @Autowired.

Вот кусок кода:

@Inject private CustomerOrderService customerOrderService;

Я не уверен в разнице между @Injectи @Autowiredбуду признателен, если кто-то объяснит их различие и какой из них использовать в какой ситуации?


3
У меня нет ответа, так как я новичок в этом тоже, но это может помочь sakaenakajima.wordpress.com/2010/08/10/…
Sagar V


2
Разница между «@Inject» и «@Autowired» хорошо объяснена в этой статье alextheedom.wordpress.com/2016/02/13/…
Алекс Тидом

Ответы:


720

Предполагая, что здесь вы имеете в виду javax.inject.Injectаннотации. @Injectявляется частью стандарта Java CDI ( внедрение контекстов и зависимостей ), представленного в Java EE 6 (JSR-299), подробнее . Spring выбрал поддержку использования @Injectсинонимов с собственной @Autowiredаннотацией.

Итак, чтобы ответить на ваш вопрос, @Autowiredэто собственная аннотация Spring. @Injectявляется частью новой технологии Java под названием CDI, которая определяет стандарт для внедрения зависимостей, аналогичный Spring. В приложении Spring эти две аннотации работают так же, как Spring решил поддержать некоторые аннотации JSR-299 в дополнение к их собственным.


115
Таким образом, теоретически, если вы использовали @Inject, вы могли бы заменить spring другой структурой DI, например Guice, и таким же образом внедрить свои зависимости.
Алекс Барнс

71
Риск быть педантичным: @Injectэто отдельный JSR (JSR-330) от CDI (JSR-299).
Брэд Купит

36
Если вы полагаетесь только на аннотации JSR- *, вы можете заменить свою DI-среду. А ты? Как только вы начали использовать Spring, скорее всего, вы использовали гораздо больше, чем просто DI. Вы не просто внесете изменения; и даже если вы это сделаете, это не несколько поиска и замены, которые сделают или сломают движение. С другой стороны, собственные аннотации Spring предлагают вам гораздо больше функциональности. Овладение хорошими фреймворками даст вам больше, чем вряд ли, использование многих.
Агостон Хорват

18
Я согласен с вами, что мы не часто меняем рамки DI. Однако, если в нашем исходном коде есть несколько пакетов, и если вы хотите создать общий пакет, который вы хотите использовать в нескольких проектах, а затем использовать @Injectаннотацию JSR, лучше использовать @Autowiredблокировку базы кода с помощью Spring DI.
Адитья

3
Использование @Injectодного не гарантирует независимость от фреймворка. Вы также должны были бы объявить инъецируемые bean-компоненты без каркасно-зависимых механизмов, таких как Spring @Componentили application.xml, но использовать @Namedи @Singletonна уровне класса. Не знаю, действительно ли какой-нибудь проект Spring сегодня объявляет такие бины - я даже никогда не слышал ни о каком проекте, который мигрировал из Spring в JEE ...
Маркус К.

162

Вот запись в блоге, которая сравнивает @Resource, @Injectи @Autowired, и, кажется, делает довольно сложную работу.

По ссылке:

За исключением теста 2 и 7, конфигурация и результаты были идентичны. Когда я заглянул под капот, я определил, что аннотации @Autowired и @Inject ведут себя одинаково. Обе эти аннотации используют AutowiredAnnotationBeanPostProcessor для внедрения зависимостей. «@Autowired» и «@Inject» можно использовать взаимозаменяемо для внедрения компонентов Spring. Однако аннотация @Resource использует CommonAnnotationBeanPostProcessor для внедрения зависимостей. Несмотря на то, что они используют разные классы постпроцессора, они ведут себя почти одинаково. Ниже приводится краткое изложение путей их выполнения.

Тесты 2 и 7, на которые ссылается автор, - это «внедрение по имени поля» и «попытка разрешить бин с использованием неверного квалификатора» соответственно.

Заключение должно предоставить вам всю необходимую информацию.


4
Эта статья является отличным объяснением трех аннотаций. Я должен был перечитать это после первого удара; но отличная статья.
Томас

1
Большое спасибо! В статье были даны ответы на несколько моих ответов, в ходе которых я обнаружил различия и сходства между Spring и JavaEE, а также на несколько других вопросов, которые у меня возникли.
Кевин Круйссен

36

Для обработки ситуации, в которой отсутствует проводка, доступны bean-компоненты с @Autowired requiredустановленным атрибутом false.

Но при использовании @Injectинтерфейс провайдера работает с бином, что означает, что бин вводится не напрямую, а с провайдером.


8
Это так важно, и было пропущено в большинстве ответов.
Игорь Донин

По умолчанию для параметра Autowired установлено значение true. Ссылка: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
спокойная

25

По состоянию Spring 3.0, Spring предлагает поддержку JSR-330 аннотации инъекций зависимостей ( @Inject, @Named, @Singleton).

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


Вопрос здесь, что вы имеете в виду, когда говорите, что Spring поддерживает JSR? Разве контейнер не поддерживает JSR, независимый от Spring, и требование к контейнеру быть совместимым с J2EE? Вы имеете в виду, что это оборачивает функциональность? Если Spring не «поддерживает» это, не будет ли аннотация из javax по-прежнему работать по умолчанию?
Дэн Чейз

Запускать Spring в контейнере JEE не обязательно, вы также можете использовать его в контейнере сервлетов / JSP, таких как Tomcat, и при этом иметь поддержку JSR-330. Spring - это отдельный DI-контейнер, он не «обменивается» компонентами CDI с хост-сервером JEE, если это то, что вы имеете в виду. Вы можете использовать CDI в контейнере JEE или Spring beans - но вы не можете использовать оба (из коробки).
Андре

22

Основное различие (замеченное при чтении документов Spring ) между @Autowiredи @Injectзаключается в том, что он @Autowiredимеет атрибут 'required', в то время как @Inject не имеет атрибута 'required'.


что ты имеешь в виду под требованием?
mattyman

2
@mattymanme Из документов: «По умолчанию автоматическое подключение завершается сбоем всякий раз, когда доступны нулевые потенциальные компоненты; поведение по умолчанию заключается в обработке аннотированных методов, конструкторов и полей как указывающих на необходимые зависимости. Это поведение можно изменить, установив для обязательного атрибута значение false ». Например:. @Autowired(required=false)Простыми словами: « requiredАтрибут указывает, что свойство не требуется для целей автоматического подключения, свойство игнорируется, если оно не может быть подключено автоматически».
Счастливчик

заглянуть в исходный код открытого интерфейса Autowired {/ ** * Объявляет, требуется ли аннотированная зависимость. * / boolean required () по умолчанию true; } Открытый интерфейс Вводят {}
Tarn

15

Лучше использовать @Inject все время. Потому что именно подход к настройке Java (предоставляемый Sun) делает наше приложение независимым от фреймворка. Так что, если вы весной, ваши занятия будут работать.

Если вы используете @Autowired, он будет работать только с пружиной, потому что @Autowired - это аннотация, предоставляемая пружиной.


13
Солнце мертво Да здравствует солнце.
Амриндер Арора

6
как часто вы собираетесь менять рамки? просто любопытно
Кей

В большинстве проектов я видел Autowired, а не Inject. Я понимаю обоснование ответа, но не могу ответить.
Витольд Качурба

13

@Autowired аннотация определяется в рамках Spring.

@Injectаннотация - это стандартная аннотация, которая определена в стандарте «Внедрение зависимостей для Java» (JSR-330) . Spring (начиная с версии 3.0) поддерживает обобщенную модель внедрения зависимостей, которая определена в стандарте JSR-330. ( Фреймворки Google Guice и Picocontainer также поддерживают эту модель).

С @Injectможет быть введена ссылка на реализацию Providerинтерфейса, которая позволяет внедрять отложенные ссылки.

Аннотации @Injectи @Autowired- это почти полные аналогии. Помимо @Autowiredаннотации, @Injectаннотацию можно использовать для свойств, методов и конструкторов автоматической привязки.

В отличие от @Autowiredаннотации, @Injectаннотация не имеет requiredатрибута. Поэтому, если зависимости не будут найдены - будет сгенерировано исключение.

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


Несмотря на то, что у @Inject нет обязательного атрибута, состояние Java Docs: требуется внедрение элементов, помеченных как @Inject. Что, по-видимому, подразумевает, что если член не найден, его ввод не удастся. См. Java Docs: docs.oracle.com/javaee/7/api/javax/inject/Inject.html
Алекс Федом


12

В дополнение к вышесказанному:

  1. Область по умолчанию для @Autowiredbean-компонентов - Singleton, тогда как при использовании @Injectаннотации JSR 330 это похоже на на прототип Spring .
  2. В JSR 330 нет эквивалента @Lazy, использующего @Inject .
  3. В использовании JSR 330 нет эквивалента @Value @Inject.

0

@InjectАннотаций является одним из коллекции JSR-330 аннотации. Это имеет соответствие по типу, соответствие по классификатору, соответствие по имени пути выполнения. Эти пути выполнения действительны как для установки, так и для внедрения в поле. Поведение @Autowiredаннотации такое же, как и у @Injectаннотации. Единственное отличие состоит в том, что @Autowiredаннотация является частью среды Spring. @Autowiredаннотация также имеет вышеуказанные пути выполнения. Поэтому я рекомендую @Autowiredдля вашего ответа.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.