wake-up-neo.net

@Resource vs @Autowired

Welche Annotation, @ Resource ( jsr25 ) oder @ Autowired (frühlingsspezifisch) soll ich in DI verwenden?

Ich habe beide in der Vergangenheit erfolgreich verwendet, @Resource(name="blah") und @Autowired @Qualifier("blah")

Mein Instinkt ist es, beim @Resource - Tag zu bleiben, da es von den Leuten von jsr ratifiziert wurde.
Hat jemand starke Gedanken dazu?

339
mlo55

Im Frühjahr vor 3.0 spielt es keine Rolle, welche.

Im Frühjahr 3.0 wird die Standardanmerkung ( JSR-3 ) @javax.inject.Inject Unterstützt - verwenden Sie sie mit einer Kombination aus @Qualifier. Beachten Sie, dass spring jetzt auch die Meta-Annotation @javax.inject.Qualifier Unterstützt:

@Qualifier
@Retention(RUNTIME)
public @interface YourQualifier {}

Also kannst du haben

<bean class="com.pkg.SomeBean">
   <qualifier type="YourQualifier"/>
</bean>

oder

@YourQualifier
@Component
public class SomeBean implements Foo { .. }

Und dann:

@Inject @YourQualifier private Foo foo;

Dies macht weniger Gebrauch von String-Namen, die falsch geschrieben werden können und schwerer zu pflegen sind.


Was die ursprüngliche Frage anbelangt: In beiden Fällen müssen Sie die Injektion nach Typ ausführen, ohne die Attribute der Annotation anzugeben. Der Unterschied ist:

  • Mit @Resource Können Sie einen Namen für die injizierte Bohne angeben
  • Mit @Autowired Können Sie es als nicht obligatorisch markieren.
176
Bozho

Sowohl @Autowired (Oder @Inject) Als auch @Resource Funktionieren gleich gut. Aber es gibt einen begrifflichen Unterschied oder einen Unterschied in der Bedeutung

  • @Resource Bedeutet, dass Sie mir ein bekannte Ressource mit Namen geben. Der Name wird aus dem Namen des mit Annotationen versehenen Setters oder Feldes extrahiert, oder er wird aus dem name-Parameter entnommen.
  • @Inject Oder @Autowired Versuchen, eine geeignete andere Komponente nach Typ einzuverdrahten.

Im Grunde sind dies also zwei ganz unterschiedliche Konzepte. Leider hat die Spring-Implementierung von @Resource Einen eingebauten Fallback, der einsetzt, wenn die Auflösung nach Namen fehlschlägt. In diesem Fall wird auf die Art der Auflösung nach Typ @Autowired Zurückgegriffen. Obwohl dieser Fallback praktisch ist, führt er meiner Meinung nach zu großer Verwirrung, da sich die Leute des konzeptionellen Unterschieds nicht bewusst sind und dazu neigen, @Resource Für typbasiertes Autowiring zu verwenden.

474
Ichthyo

Der Hauptunterschied ist, @Autowired ist eine Frühlingsanmerkung. Wohingegen @Resource wird vom JSR-250 spezifiziert, wie Sie selbst betont haben. Das letztere ist also Teil von Java, während das erstere Spring-spezifisch ist.

Sie haben also Recht, wenn Sie dies in gewissem Sinne vorschlagen. Ich fand Leute verwenden @Autowired mit @Qualifier weil es mächtiger ist. Der Wechsel von einem Framework zu einem anderen wird als sehr unwahrscheinlich angesehen, wenn nicht sogar als Mythos, insbesondere im Fall von Spring.

72
Adeel Ansari

Ich möchte einen Kommentar von @ Jules am diese Antwort zu dieser Frage hervorheben. Der Kommentar enthält einen nützlichen Link: Spring Injection mit @Resource, @Autowired und @Inject . Ich ermutige Sie, es vollständig zu lesen, aber hier ist eine kurze Zusammenfassung seiner Nützlichkeit:

Wie wählen Annotationen die richtige Implementierung aus?

@Autowired Und @Inject

  1. Übereinstimmungen nach Typ
  2. Einschränkungen durch Qualifier
  3. Übereinstimmungen nach Namen

@Resource

  1. Übereinstimmungen nach Namen
  2. Übereinstimmungen nach Typ
  3. Einschränkungen durch Qualifikatoren (werden ignoriert, wenn eine Übereinstimmung anhand des Namens gefunden wird)

Welche Anmerkungen (oder Kombinationen von) sollte ich zum Injizieren meiner Bohnen verwenden?

  1. Nennen Sie Ihre Komponente explizit [@Component ("beanName")]

  2. Verwenden Sie @Resource Mit dem name-Attribut [@Resource (name = "beanName")]

Warum sollte ich @Qualifier Nicht verwenden?

Vermeiden Sie Annotationen @Qualifier, Es sei denn, Sie möchten eine Liste ähnlicher Beans erstellen. Beispielsweise möchten Sie möglicherweise einen Regelsatz mit einer bestimmten @Qualifier - Anmerkung markieren. Dieser Ansatz vereinfacht das Einfügen einer Gruppe von Regelklassen in eine Liste, die zum Verarbeiten von Daten verwendet werden kann.

Verlangsamt die Bohneninjektion mein Programm?

Bestimmte Pakete nach Komponenten durchsuchen [context:component-scan base-package="com.sourceallies.person"]. Dies führt zwar zu mehr component-scan - Konfigurationen, verringert jedoch die Wahrscheinlichkeit, dass Sie Ihrem Spring-Kontext unnötige Komponenten hinzufügen.


Referenz:Federeinspritzung mit @Resource, @Autowired und @Inject

63
Stephan

Folgendes habe ich aus dem Spring 3.0.x Referenzhandbuch erhalten: -

Spitze

Wenn Sie annotationsgesteuerte Injection nach Namen ausdrücken möchten, verwenden Sie in erster Linie nicht @Autowired, auch wenn technisch in der Lage ist, über @Qualifier-Werte auf einen Bean-Namen zu verweisen. Verwenden Sie stattdessen die Anmerkung JSR-250 @Resource, die semantisch definiert ist, um eine bestimmte Zielkomponente anhand ihres eindeutigen Namens zu identifizieren, wobei der deklarierte Typ für den Abgleichsprozess irrelevant ist.

Infolge dieses semantischen Unterschieds können Beans, die selbst als Auflistungs- oder Map-Typ definiert sind, nicht über @Autowired injiziert werden, da die Typzuordnung für sie nicht ordnungsgemäß anwendbar ist. Verwenden Sie @Resource für solche Beans und verweisen Sie dabei auf die jeweilige Collection oder Map Bean mit einem eindeutigen Namen.

@Autowired gilt für Felder, Konstruktoren und Methoden mit mehreren Argumenten und ermöglicht das Eingrenzen durch Qualifiziereranmerkungen auf Parameterebene. Im Gegensatz dazu wird @Resource nur für Felder und Bean-Eigenschaftssetzmethoden mit einem einzelnen Argument unterstützt. Halten Sie sich daher an Qualifikatoren, wenn Ihr Injektionsziel ein Konstruktor oder eine Methode mit mehreren Argumenten ist.

38
Kartik

@Autowired + @Qualifier funktioniert nur mit Spring DI, wenn Sie in Zukunft eine andere DI verwenden möchten. @Resource ist eine gute Option.

ein weiterer Unterschied, den ich als sehr bedeutend empfand, ist, dass @Qualifier keine dynamische Bean-Verkabelung unterstützt, da @Qualifier keine Platzhalter unterstützt, während @Resource dies sehr gut tut.

Beispiel: Wenn Sie eine Schnittstelle mit mehreren Implementierungen wie dieser haben

interface parent {

}
@Service("actualService")
class ActualService implements parent{

}
@Service("stubbedService")
class SubbedService implements parent{

}

mit @Autowired & @Qualifier müssen Sie bestimmte untergeordnete Implementierungen wie festlegen

@Autowired
@Qualifier("actualService") or 
@Qualifier("stubbedService") 
Parent object;

dies stellt keinen Platzhalter bereit, während Sie mit @Resource Platzhalter setzen und mithilfe der Eigenschaftendatei eine bestimmte untergeordnete Implementierung wie einfügen können

@Resource(name="${service.name}")
Parent object;  

dabei wird service.name in der Eigenschaftendatei als festgelegt

#service.name=actualService
 service.name=stubbedService

Hoffe das hilft jemandem :)

20
Ali

Beide sind gleich gut. Der Vorteil der Verwendung von Resource besteht in der Zukunft darin, dass Ihre Codeänderungen viel einfacher sind, wenn Sie ein anderes DI-Framework als spring verwenden möchten. Mit Autowired ist Ihr Code fest mit den Federn DI verbunden.

16
Teja Kantamneni

Wenn Sie die Basisklassen dieser beiden Annotationen kritisch analysieren, werden Sie die folgenden Unterschiede feststellen.

@Autowired verwendet AutowiredAnnotationBeanPostProcessor, um Abhängigkeiten einzufügen.
@Resource verwendet CommonAnnotationBeanPostProcessor, um Abhängigkeiten einzufügen.

Obwohl sie unterschiedliche Postprozessor-Klassen verwenden, verhalten sich alle nahezu identisch. Die Unterschiede liegen kritisch in ihren Ausführungspfaden, die ich unten hervorgehoben habe.

@Autowired / @Inject

1. Übereinstimmungen nach Typ
2. Einschränkungen durch Qualifikanten
3. Übereinstimmungen nach Namen

@Resource

1. Übereinstimmungen nach Namen
2. Übereinstimmungen nach Typ
3. Einschränkungen nach Qualifikationsmerkmalen (wird ignoriert, wenn eine Übereinstimmung nach Namen gefunden wird)

10
Amos Kosgei

Mit @Resource Sie können Beans selbst injizieren. Dies kann erforderlich sein, um alle zusätzlichen Logikfunktionen auszuführen, die von Beans-Postprozessoren wie Transaktions- oder Sicherheitsfunktionen hinzugefügt wurden.

Mit Spring 4.3+ @Autowired kann das auch.

4

@Resource wird häufig von übergeordneten Objekten verwendet, die über JNDI definiert wurden. @Autowired oder @Inject wird von häufigeren Bohnen verwendet.

Soweit ich weiß, handelt es sich weder um eine Spezifikation noch um eine Konvention. Es ist logischer, wie Standard-Code diese Annotationen verwendet.

2
Nicolas Zozol

Als Anmerkung hier: SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext und SpringBeanAutowiringSupport.processInjectionBasedOnServletContextNICHT arbeite mit @Resource Anmerkung. Es gibt also Unterschiede.

0
msangel