Яка різниця між @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/…
Alex Theedom

Відповіді:


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, ви можете замінити весну на іншу рамку DI, наприклад, Guice та ввести свої залежності таким же чином.
Алекс Барнс

71
Ризик бути педантичним: @Injectце окремий JSR (JSR-330) від CDI (JSR-299).
Бред Купіт

36
Якщо ви покладаєтесь лише на анотації JSR- *, обов'язково ви можете замінити вам рамки DI. Але ти будеш? Після того, як ви почали використовувати весну, швидше за все, ви використали її набагато більше, ніж просто DI. Ви не просто внесите зміни; і навіть якщо ви зробите це, то не лише кілька пошукових і замінюючих дій будуть робити або порушувати рух. З іншого боку, власні анотації Spring пропонують вам набагато більше функціональних можливостей. Оволодіння хорошими рамками дасть вам більше, ніж навряд чи багато хто.
Agoston Horvath

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

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

162

Ось допис у блозі, який порівнює @Resource, @Injectта @Autowired, і, схоже, виконує досить всебічну роботу.

За посиланням:

За винятком тесту 2 та 7, конфігурація та результати були однаковими. Коли я заглянув під капот, я визначив, що анотація "@Autwired" та "@Inject" поводяться однаково. Обидва цих анотації використовують "AutowiredAnnotationBeanPostProcessor" для введення залежностей. "@Autowired" і "@Inject" можна використовувати як взаємозамінні для введення яєць. Однак анотація "@Resource" використовує "CommonAnnotationBeanPostProcessor" для введення залежностей. Незважаючи на те, що вони використовують різні класи після процесорів, вони поводяться майже однаково. Нижче наведено короткий опис шляхів їх виконання.

Тести 2 та 7, на які автор посилається, є "ін'єкція за назвою поля" та "спроба розв'язати боб за допомогою поганого класифікатора" відповідно.

Висновок повинен дати вам всю необхідну інформацію.


4
Ця стаття є чудовим поясненням трьох анотацій. Мені довелося перечитати її після першого перенесення; але, відмінна стаття.
Томас

1
Дуже дякую! Стаття відповіла на кілька моїх відповідей в пошуку пошуку відмінностей та подібності між Spring та JavaEE, а також на кілька інших питань, які у мене виникли.
Кевін Кройсейсен

36

Для вирішення ситуації, коли немає проводки, доступні боби з @Autowired requiredатрибутом, встановленим на false.

Але при використанні @Injectінтерфейс Постачальника працює з бобом, що означає, що квасоля вводиться не безпосередньо, а з Провайдером.


8
Це настільки важливо, і це було пропущено у відповідях, які найбільше підтримують.
Ігор Донін

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

25

Станом Spring 3.0, Spring пропонує підтримку JSR-330 для ін'єкцій залежностей анотацій ( @Inject, @Named,@Singleton ).

У весняній документації про них є окремий розділ , включаючи порівняння їх еквівалентів Spring.


Питання тут, що ви маєте на увазі, коли Ви говорите, що Spring підтримує JSR? Чи контейнер не підтримує JSR незалежно від Spring, а вимога, щоб контейнер відповідав J2EE? Ви маєте на увазі, що він охоплює функціональність? Якби Spring не "підтримав" це, чи не залишилося б примітка від javax за замовчуванням?
Ден Чейз

Не обов’язково запускати Spring в контейнер JEE, ви також можете використовувати його в контейнері сервлет / JSP, як Tomcat, і все ще має підтримку JSR-330. Spring - це окремий контейнер DI, він не "обмінюється" CDI-бобами з хостовим сервером JEE, якщо це те, що ви маєте на увазі. Ви можете або використовувати CDI в контейнері JEE, або яєчну квасолю - але ви не можете використовувати обидва (поза коробкою).
Andre Steingress

22

Ключова відмінність (помічена під час читання Spring Docs ) між @Autowiredі @Injectполягає в тому, що @Autowiredмає атрибут "обов'язковий", а в атрибута @Inject немає "необхідного".


Що ти означає під необхідним?
mattyman

2
@mattymanme В документах: "За замовчуванням автоматичне підключення виходить з ладу щоразу, коли доступні нульові боби-кандидати; поведінка за замовчуванням - це трактувати анотовані методи, конструктори та поля як вказівки на необхідні залежності. Цю поведінку можна змінити, встановивши потрібний атрибут на значення false ". Наприклад:. @Autowired(required=false)Простими словами, " requiredАтрибут вказує на те, що властивість не потрібна для автоматичної проводки. Властивість ігнорується, якщо її неможливо виконати з автоматичним з'єднанням".
Лаки

шукайте у вихідному коді загальнодоступний інтерфейс Autowired {/ ** * Оголошує, чи потрібна анотована залежність. * / обов'язкове boolean (() за замовчуванням; } публічний інтерфейс Inject {}
tarn

15

Краще використовувати @Inject весь час. Оскільки саме конфігурація Java (надається сонцем) робить наш додаток агностичним для фреймворку. Тож якщо весною теж будуть працювати ваші заняття.

Якщо ви використовуєте @Autowired, він працює лише з весною, оскільки @Autowired весною надається анотація.


13
Сонце мертве. Хай живе сонце.
Amrinder Arora

6
як часто ви збираєтесь змінювати рамки? просто цікаво
Kay

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

13

@Autowired анотація визначена у рамках весни.

@Injectанотація - це стандартна анотація, яка визначена в стандарті "Ін'єкція залежності для Java" (JSR-330) . Весна (починаючи з версії 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.oracle.com/javaee/7/api/javax/inject/Inject.html
Alex Theedom


12

На додаток до вищезазначеного:

  1. Область застосування для @Autowiredбобів за замовчуванням - Singleton, тоді як використання @Injectанотації JSR 330 - це як прототип Spring .
  2. У JSR 330 не існує еквівалента @Lazy @Inject.
  3. У JSR 330 не існує еквівалента @Value @Inject.

0

@InjectАнотацій є одним з колекції JSR-330 анотації. У ньому є відповідність за типом, збіг за кваліфікаційним рівнем, відповідність шляхів виконання за назвою. Ці контури виконання дійсні як для встановлення, так і для введення поля. Поведінка @Autowiredанотації така ж, як і @Injectпримітка. Єдина відмінність полягає в тому, що @Autowiredанотація є частиною весняних рамок. @Autowiredанотація також має вищезазначені шляхи виконання. Тому я рекомендую відповідь @Autowiredдля вашої відповіді.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.