Was ist der Unterschied zwischen @Inject und @Autowired in Spring Framework? Welches unter welchen Bedingungen zu verwenden?

695

Ich gehe einige Blogs auf SpringSource durch und in einem der Blogs verwendet der Autor @Injectund ich nehme an, er kann es auch verwenden @Autowired.

Hier ist der Code:

@Inject private CustomerOrderService customerOrderService;

Ich bin mir nicht sicher über den Unterschied zwischen @Injectund @Autowiredund würde es begrüßen, wenn jemand seinen Unterschied erklärt und welchen ich in welcher Situation verwenden soll.

Rachel
quelle
3
Ich habe keine Antwort, da ich auch neu darin bin, aber dies könnte helfen, sakaenakajima.wordpress.com/2010/08/10/…
Sagar V
2
Der Unterschied zwischen '@Inject' und '@Autowired' wird in diesem Artikel gut
Alex Theedom

Antworten:

719

Angenommen, Sie beziehen sich hier auf die javax.inject.InjectAnmerkungen. @Injectist Teil des in CD EE 6 (JSR-299) eingeführten Java CDI- Standards ( Contexts and Dependency Injection ). Lesen Sie mehr . Spring hat sich dafür entschieden, die Verwendung @Injectsynonym mit eigenen @AutowiredAnmerkungen zu unterstützen.

Um Ihre Frage zu beantworten, @Autowiredist Spring's eigene Anmerkung. @Injectist Teil einer neuen Java-Technologie namens CDI, die einen Standard für die Abhängigkeitsinjektion ähnlich wie Spring definiert. In einer Spring-Anwendung funktionieren die beiden Anmerkungen genauso, wie Spring beschlossen hat, einige JSR-299-Anmerkungen zusätzlich zu ihren eigenen zu unterstützen.

Brei
quelle
115
Wenn Sie also @Inject verwenden, können Sie die Feder theoretisch durch ein anderes DI-Framework ersetzen, z. B. Guice, und Ihre Abhängigkeiten auf die gleiche Weise einfügen.
Alex Barnes
71
Es besteht die Gefahr, pedantisch zu sein: Es @Injecthandelt sich um ein von CDI (JSR-299) getrenntes JSR (JSR-330).
Brad Cupit
36
Wenn Sie sich nur auf JSR- * -Anmerkungen verlassen, können Sie Ihr DI-Framework natürlich ersetzen. Aber wirst du? Sobald Sie mit Spring begonnen haben, haben Sie wahrscheinlich viel mehr davon verwendet als nur DI. Sie werden nicht nur eine Änderung vornehmen. und selbst wenn Sie dies tun, werden nicht wenige Suchen und Ersetzen den Schritt machen oder brechen. Auf der anderen Seite bieten Ihnen die eigenen Anmerkungen von Spring viel mehr Funktionen. Wenn Sie ein gutes Framework beherrschen, können Sie mehr als kaum viele verwenden.
Agoston Horvath
18
Ich stimme Ihnen zu, dass wir die DI-Frameworks nicht oft ändern. Wenn unser Quellcode jedoch mehrere Pakete enthält und Sie ein gemeinsames Paket erstellen möchten, das Sie für mehrere Projekte freigeben möchten, und dann eine @InjectJSR-Annotation verwenden möchten, ist es besser, wenn Sie die @AutowiredCodebasis mit Spring DI sperren.
Aditya
3
Die @Injectalleinige Verwendung gewährleistet keine Rahmenunabhängigkeit. Sie müssten auch injizierbare Beans ohne Framework-abhängige Mechanismen wie Spring's @Componentoder deklarieren application.xml, aber verwenden @Namedund @Singletonauf Klassenebene. Keine Ahnung, ob ein Spring-Projekt heute wirklich solche Bohnen deklariert - ich habe noch nie von einem Projekt gehört, das von Spring nach JEE migriert ist ...
Marcus K.
162

Hier ist ein Blog-Beitrag@Resource , der @Inject, und @Autowired, vergleicht und einen ziemlich umfassenden Job zu machen scheint.

Über den Link:

Mit Ausnahme von Test 2 und 7 waren Konfiguration und Ergebnisse identisch. Als ich unter die Haube schaute, stellte ich fest, dass sich die Anmerkungen '@Autowired' und '@Inject' identisch verhalten. Beide Annotationen verwenden den 'AutowiredAnnotationBeanPostProcessor', um Abhängigkeiten einzufügen. '@Autowired' und '@Inject' können austauschbar verwendet werden, um Spring Beans zu injizieren. Die Annotation '@Resource' verwendet jedoch den 'CommonAnnotationBeanPostProcessor', um Abhängigkeiten einzufügen. Obwohl sie unterschiedliche Postprozessorklassen verwenden, verhalten sich alle nahezu identisch. Unten finden Sie eine Zusammenfassung ihrer Ausführungspfade.

Test 2 und 7, auf die der Autor verweist, sind "Injektion nach Feldname" bzw. "Versuch, eine Bean mit einem schlechten Qualifikationsmerkmal aufzulösen".

Die Schlussfolgerung sollte Ihnen alle Informationen geben, die Sie benötigen.

nicholas.hauschild
quelle
4
Dieser Artikel ist eine großartige Erklärung für die drei Anmerkungen. Ich musste es nach dem ersten Schlag noch einmal lesen; aber ein ausgezeichneter Artikel.
Thomas
1
Vielen Dank! Der Artikel beantwortete mehrere meiner Antworten auf meiner Suche nach den Unterschieden und Ähnlichkeiten zwischen Spring und JavaEE sowie einige andere Fragen, die ich hatte.
Kevin Cruijssen
36

Um die Situation zu bewältigen, in der keine Verkabelung vorhanden ist, sind Beans mit dem @Autowired requiredAttribut auf verfügbar false.

Bei Verwendung @Injectfunktioniert die Provider-Schnittstelle jedoch mit der Bean, was bedeutet, dass die Bean nicht direkt, sondern mit dem Provider injiziert wird.

amits
quelle
8
Dies ist so wichtig und wurde in den am besten bewerteten Antworten übersehen.
Igor Donin
Standardmäßig ist der erforderliche Parameter für Autowired auf true gesetzt. Ref: docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
ruhig
25

Ab Frühling 3.0, Frühling bietet Unterstützung für JSR-330 Dependency Injection Anmerkungen ( @Inject, @Named, @Singleton).

In der Spring-Dokumentation gibt es einen separaten Abschnitt über sie, einschließlich Vergleiche mit ihren Spring-Äquivalenten.

Andre Steingress
quelle
Frage hier, was meinst du, wenn du sagst, dass Spring JSR unterstützt? Unterstützt der Container JSR nicht unabhängig von Spring und muss der Container J2EE-konform sein? Meinen Sie damit, dass es die Funktionalität einschließt? Wenn Spring es nicht "unterstützt" hätte, würde die Annotation von javax dann nicht standardmäßig noch funktionieren?
Dan Chase
Es ist kein Muss, Spring in einem JEE-Container auszuführen. Sie können es auch in einem Servlet- / JSP-Container wie Tomcat verwenden und trotzdem JSR-330 unterstützen. Spring ist ein separater DI-Container, der CDI-Beans nicht mit dem Host-JEE-Server "austauscht", wenn es das ist, was Sie meinen. Sie können entweder CDI in einem JEE-Container oder Spring Beans verwenden - aber Sie können nicht beide verwenden (sofort einsatzbereit).
Andre Steingress
22

Der Hauptunterschied (der beim Lesen der Spring Docs festgestellt wird ) zwischen @Autowiredund @Injectbesteht darin, dass @Autowireddas Attribut 'erforderlich' vorhanden ist, während das @Inject kein Attribut 'erforderlich' hat.

Glücklich
quelle
Was meinst du mit erforderlich?
Mattyman
2
@mattymanme In den Dokumenten heißt es: "Standardmäßig schlägt die automatische Verdrahtung fehl, wenn keine Kandidaten-Beans verfügbar sind. Das Standardverhalten besteht darin, kommentierte Methoden, Konstruktoren und Felder als Hinweis auf erforderliche Abhängigkeiten zu behandeln. Dieses Verhalten kann geändert werden, indem das erforderliche Attribut auf false gesetzt wird ". Beispiel: @Autowired(required=false)In einfachen Worten: "Das requiredAttribut gibt an, dass die Eigenschaft nicht für die automatische Verdrahtung erforderlich ist. Die Eigenschaft wird ignoriert, wenn sie nicht automatisch verdrahtet werden kann."
Glücklicher
Schauen Sie in die öffentliche Schnittstelle des Quellcodes. Autowired {/ ** * Gibt an, ob die mit Anmerkungen versehene Abhängigkeit erforderlich ist. * / boolean required () default true; } öffentliche Schnittstelle Inject {}
Tarn
15

Verwenden Sie besser immer @Inject. Weil es der Java-Konfigurationsansatz (von sun bereitgestellt) ist, der unsere Anwendung unabhängig vom Framework macht. Wenn Sie also Frühling haben, werden auch Ihre Klassen funktionieren.

Wenn Sie @Autowired verwenden, funktioniert dies nur mit spring, da @Autowired eine von Spring bereitgestellte Anmerkung ist.

tech.yenduri
quelle
13
Die Sonne ist tot. Es lebe die Sonne.
Amrinder Arora
6
Wie oft werden Sie das Framework ändern? nur neugierig
Kay
Bei den meisten Projekten habe ich eher Autowired als Inject gesehen. Ich verstehe die Begründung der Antwort, kann aber nicht zustimmen.
Witold Kaczurba
13

@Autowired Annotation wird im Spring-Framework definiert.

@InjectAnnotation ist eine Standard-Annotation, die im Standard "Dependency Injection for Java" (JSR-330) definiert ist . Spring (seit Version 3.0) unterstützt das verallgemeinerte Modell der Abhängigkeitsinjektion, das im Standard JSR-330 definiert ist. ( Google Guice-Frameworks und Picocontainer-Framework unterstützen dieses Modell ebenfalls).

Mit @Injectkann die Referenz auf die Implementierung der ProviderSchnittstelle eingefügt werden, wodurch die zurückgestellten Referenzen eingefügt werden können.

Anmerkungen @Injectund @Autowired- sind fast vollständige Analogien. Sowie @AutowiredAnnotation, @InjectAnmerkung kann für die automatische Bindeeigenschaften, Methoden und Konstruktoren verwendet werden.

Im Gegensatz zur @AutowiredAnnotation hat die @InjectAnnotation kein requiredAttribut. Wenn die Abhängigkeiten nicht gefunden werden, wird daher eine Ausnahme ausgelöst.

Es gibt auch Unterschiede in der Klärung der Bindungseigenschaften. Wenn bei der Auswahl der Komponenten für die Injektion Unklarheiten bestehen, @Namedsollte der Qualifizierer hinzugefügt werden. In einer ähnlichen Situation wird für @AutowiredAnnotation ein @QualifierQualifier hinzugefügt (JSR-330 definiert seine eigene @QualifierAnnotation und über diesen Qualifier wird Annotation @Nameddefiniert).

Arash
quelle
Obwohl das '@Inject' kein erforderliches Attribut hat, ist der Java Docs-Status: Die Injektion von Mitgliedern, die mit '@Inject' versehen sind, ist erforderlich. Dies scheint zu implizieren, dass die Injektion fehlschlägt, wenn ein Mitglied nicht gefunden wird. Siehe Java Docs: docs.oracle.com/javaee/7/api/javax/inject/Inject.html
Alex Theedom
12

@Inject hat kein 'erforderliches' Attribut

Mykhaylo Adamovych
quelle
12

Zusätzlich zum oben genannten:

  1. Der Standardbereich für @AutowiredBeans ist Singleton, während die Verwendung der JSR 330- @InjectAnnotation dem Prototyp von Spring ähnelt .
  2. In JSR 330 gibt es kein Äquivalent zu @Lazy @Inject.
  3. In JSR 330 gibt es kein Äquivalent zu @Value using @Inject.
Keyur Vyas
quelle
0

Die @InjectAnnotation ist eine der JSR-330-Annotationssammlungen. Dies hat Ausführungspfade Match by Type, Match by Qualifier, Match by Name. Diese Ausführungspfade gelten sowohl für die Setter- @Autowiredals auch für die @InjectFeldinjektion. Das Verhalten der Annotation entspricht dem der Annotation. Der einzige Unterschied besteht darin, dass die @AutowiredAnmerkung Teil des Spring-Frameworks ist. @AutowiredAnnotation hat auch die obigen Ausführungspfade. Also empfehle ich das @Autowiredfür deine Antwort.

Kushani5j
quelle