Jaka jest różnica między @Inject a @Autowired w Spring Framework? Którego użyć pod jakim warunkiem?


695

Przeglądam blogi na SpringSource, a na jednym z blogów autor używa @Injecti przypuszczam, że on też może z niego korzystać @Autowired.

Oto fragment kodu:

@Inject private CustomerOrderService customerOrderService;

Nie jestem pewien różnicy między @Injecti @Autowireddoceniłbym to, gdyby ktoś wyjaśnił ich różnicę i którego użyć w jakiej sytuacji?


3
Nie mam odpowiedzi, ponieważ ja też jestem w tym nowy, ale to może pomóc sakaenakajima.wordpress.com/2010/08/10/…
Sagar V


2
Różnica między „@Inject” i „@Autowired” jest dobrze wyjaśniona w tym artykule, alextheedom.wordpress.com/2016/02/13/…
Alex Theedom

Odpowiedzi:


720

Zakładając, że masz na myśli javax.inject.Injectadnotacje. @Injectjest częścią standardu Java CDI ( Contexts and Dependency Injection ) wprowadzonego w Javie EE 6 (JSR-299), czytaj więcej . Spring zdecydował się wspierać używanie @Injectsynonimów z ich własnymi @Autowiredadnotacjami.

Tak więc, aby odpowiedzieć na twoje pytanie, @Autowiredjest własna adnotacja Springa. @Injectjest częścią nowej technologii Java o nazwie CDI, która definiuje standard wstrzykiwania zależności podobny do Springa. W aplikacji Spring te dwie adnotacje działają w taki sam sposób, jak Spring postanowił wesprzeć niektóre adnotacje JSR-299 oprócz własnych.


115
Więc teoretycznie, jeśli użyłeś @Inject, możesz zastąpić sprężynę inną strukturą DI, np. Guice i wstrzyknąć swoje zależności w ten sam sposób.
Alex Barnes,

71
Ryzykuje pedantyczny: @Injectjest oddzielnym JSR (JSR-330) od CDI (JSR-299).
Brad Cupit,

36
Jeśli opierać się na JSR- * adnotacje tylko upewnić, że może zastąpić ci ramy DI. Ale czy ty Gdy zaczniesz używać wiosny, prawdopodobnie zużyłeś o wiele więcej niż tylko DI. Nie tylko zrobisz zmianę; a nawet jeśli to zrobisz, nie jest to kilka wyszukiwań i zamień, które dokonają lub przerwie ruch. Z drugiej strony, własne adnotacje Springa oferują znacznie większą funkcjonalność. Opanowanie dobrego frameworka da ci więcej niż prawie niemożliwe korzystanie z wielu.
Agoston Horvath,

18
Zgadzam się z tobą, że często nie zmieniamy frameworków DI. Jeśli jednak nasz kod źródłowy ma wiele pakietów i jeśli chcesz zbudować wspólny pakiet, który chcesz udostępnić w wielu projektach, a następnie skorzystanie z @Injectadnotacji JSR jest lepsze niż użycie tego, @Autowiredktóry blokuje bazę kodu za pomocą sprężyny DI.
Aditya

3
Używanie w @Injectpojedynkę nie zapewni niezależności ram. Można by też trzeba zadeklarować fasoli wstrzyknięć bez mechanizmów zależnych ramowych, takich jak sprężyny @Componentlub application.xml, ale użytku @Namedi @Singletonna poziomie klasy. Nie mam pojęcia, czy jakikolwiek projekt wiosenny tak naprawdę deklaruje dzisiaj taką fasolę - nigdy nie słyszałem o żadnym projekcie, który migrował z Spring do JEE ...
Marcus K.,

162

Oto blogu , który porównuje @Resource, @Injecti @Autowired, i wydaje się zrobić całkiem wyczerpujące zadanie.

Z linku:

Z wyjątkiem testu 2 i 7 konfiguracja i wyniki były identyczne. Kiedy spojrzałem pod maską, stwierdziłem, że adnotacje „@Autowired” i „@Inject” zachowują się identycznie. Obie te adnotacje używają „AutowiredAnnotationBeanPostProcessor” do wstrzykiwania zależności. „@Autowired” i „@Inject” mogą być używane zamiennie do iniekcji fasoli jarej. Jednak adnotacja „@Resource” używa „CommonAnnotationBeanPostProcessor” do wstrzykiwania zależności. Mimo że używają różnych klas postprocesorów, wszystkie zachowują się prawie identycznie. Poniżej znajduje się podsumowanie ścieżek ich wykonania.

Testy 2 i 7, w których autor odwołuje się, to odpowiednio „wstrzyknięcie według nazwy pola” i „próba rozwiązania problemu z komponentem bean przy użyciu złego kwalifikatora”.

Wniosek powinien zawierać wszystkie potrzebne informacje.


4
Ten artykuł jest doskonałym wyjaśnieniem trzech adnotacji. Musiałem przeczytać go ponownie po pierwszym przesunięciu; ale świetny artykuł.
Thomas

1
Wielkie dzięki! Artykuł odpowiedział na wiele moich odpowiedzi w moich poszukiwaniach różnic i podobieństw między Spring i JavaEE, a także na kilka innych pytań, które miałem.
Kevin Cruijssen

36

Aby poradzić sobie z sytuacją, w której nie ma okablowania, dostępne są fasole z @Autowired requiredatrybutem ustawionym na false.

Ale podczas używania @Injectinterfejs dostawcy działa z komponentem bean, co oznacza, że ​​fasola nie jest wstrzykiwana bezpośrednio, ale z operatorem.


8
Jest to bardzo ważne i zostało przeoczone w najbardziej pozytywnych odpowiedziach.
Igor Donin

Domyślnie wymagany parametr jest ustawiony na wartość true dla opcji Autowired. Ref: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
spokojny

25

Od wiosny 3.0 oferty sprężynowe wsparcie JSR-330 opisów wtrysku zależność ( @Inject, @Named, @Singleton).

Jest to osobny rozdział w dokumentacji wiosennego o nich, w tym porównań do ich odpowiedników wiosnę.


Pytanie tutaj, co masz na myśli mówiąc, że Wiosna wspiera JSR? Czy kontener nie obsługuje JSR niezależnego od Springa i czy jest on zgodny z J2EE? Czy masz na myśli to, że otacza funkcjonalność? Gdyby Spring go nie obsługiwał, czy adnotacja z javax nadal nie działałaby domyślnie?
Dan Chase

Uruchomienie Springa w kontenerze JEE nie jest konieczne, możesz go również użyć w kontenerze serwletu / JSP, takim jak Tomcat, i nadal mieć obsługę JSR-330. Wiosna jest osobnym kontenerem DI, nie „zamienia” ziaren CDI z hostem JEE, jeśli to masz na myśli. Możesz albo użyć CDI w kontenerze JEE, albo fasolki szparagowej - ale nie możesz użyć obu (po wyjęciu z pudełka).
Andre Steingress,

22

Kluczowa różnica (zauważona podczas czytania Spring Docs ) pomiędzy @Autowiredi @Injectpolega na tym, że @Autowiredma atrybut „wymagany”, podczas gdy @Inject nie ma atrybutu „wymagany”.


co rozumiesz przez wymagane?
mattyman

2
@mattymanme Z dokumentów: „Domyślnie automatyczne wiązanie nie powiedzie się, gdy dostępnych jest zero kandydujących komponentów bean; domyślnym zachowaniem jest traktowanie metod z adnotacjami, konstruktorów i pól jako wskazujących wymagane zależności. To zachowanie można zmienić, ustawiając wymagany atrybut na wartość false „. Np .: @Autowired(required=false)W prostych słowach: requiredAtrybut wskazuje, że właściwość nie jest wymagana do celów automatycznego okablowania, właściwość jest ignorowana, jeśli nie można jej automatycznie przypisać”.
Lucky

zajrzyj do publicznego interfejsu kodu źródłowego Autowired {/ ** * Deklaruje, czy wymagana jest zależność z adnotacjami. * / boolean wymagany () domyślny true; } interfejs publiczny Inject {}
tarn

15

Lepiej używaj @Inject przez cały czas. Ponieważ to podejście do konfiguracji Java (dostarczone przez sun) sprawia, że ​​nasza aplikacja jest agnostyczna w stosunku do frameworka. Więc jeśli wiosną, również twoje klasy będą działać.

Jeśli użyjesz @Autowired, będzie działał tylko ze sprężyną, ponieważ @Autowired jest opatrzony wiosną pod adnotacją.


13
Słońce nie żyje. Niech żyje słońce.
Amrinder Arora,

6
jak często zamierzasz zmieniać ramy? po prostu ciekawy
Kay

W większości projektów widziałem raczej Autowired niż Inject. Rozumiem uzasadnienie odpowiedzi, ale nie mogę głosować pozytywnie.
Witold Kaczurba

13

@Autowired adnotacja jest zdefiniowana w ramach Spring.

@Injectadnotacja to standardowa adnotacja zdefiniowana w standardowym „Dependency Injection for Java” (JSR-330) . Wiosna (od wersji 3.0) obsługuje uogólniony model wstrzykiwania zależności, który jest zdefiniowany w standardowym JSR-330. ( Ramy Google Guice i Picocontainer również obsługują ten model).

Za pomocą @Injectmożna wstrzyknąć odniesienie do implementacji Providerinterfejsu, co umożliwia wstrzyknięcie odroczonych odniesień.

Adnotacje @Injecti @Autowired- to prawie kompletne analogie. Oprócz @Autowiredadnotacji, @Injectadnotacji można używać do automatycznego wiązania właściwości, metod i konstruktorów.

W przeciwieństwie do @Autowiredadnotacji, @Injectadnotacja nie ma requiredatrybutu. Dlatego jeśli zależności nie zostaną znalezione - zostanie zgłoszony wyjątek.

Istnieją również różnice w wyjaśnieniach właściwości wiązania. Jeśli wybór komponentów do iniekcji jest niejasny, @Namednależy dodać kwalifikator. W podobnej sytuacji do @Autowiredadnotacji zostanie dodany @Qualifierkwalifikator (JSR-330 definiuje własną @Qualifieradnotację i za pomocą tego kwalifikatora @Nameddefiniowana jest adnotacja ).


Mimo że „@Inject” nie ma wymaganego atrybutu, stan Dokumentów Java: wymagane jest wstrzyknięcie elementów z adnotacją „@Inject”. Co wydaje się sugerować, że jeśli członek nie zostanie znaleziony, jego wstrzyknięcie zakończy się niepowodzeniem. Zobacz Dokumenty Java: docs.oracle.com/javaee/7/api/javax/inject/Inject.html
Alex Theedom


12

W dodatku do powyższego:

  1. Domyślny zakres dla @Autowiredziaren to Singleton, natomiast przy użyciu @Injectadnotacji JSR 330 jest to jak prototyp Springa .
  2. W JSR 330 nie ma odpowiednika @Lazy @Inject.
  3. W JSR 330 nie ma odpowiednika @Value @Inject.

0

@InjectAdnotacja jest zbioru JSR-330 adnotacje. Zawiera ścieżki realizacji typu Dopasuj według typu, Dopasuj według kwalifikatora, Dopasuj według nazwy. Te ścieżki wykonywania są poprawne zarówno dla setera, jak i wstrzykiwania w polu. Zachowanie @Autowiredadnotacji jest takie samo jak @Injectadnotacja. Jedyną różnicą jest to, że @Autowiredadnotacja jest częścią struktury Spring. @Autowiredadnotacja ma również powyższe ścieżki wykonania. Więc polecam @Autowireddla twojej odpowiedzi.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.