Welche Annotation, @Resource ( jsr250 ) oder @Autowired (Spring-spezifisch), sollte ich in DI verwenden?
Ich habe erfolgreich eingesetzt , sowohl in der Vergangenheit, @Resource(name="blah")
und@Autowired @Qualifier("blah")
Mein Instinkt ist es, bei dem @Resource
Tag zu bleiben, da es von den jsr-Leuten ratifiziert wurde.
Hat jemand starke Gedanken dazu?
Antworten:
Im Frühjahr vor 3.0 spielt es keine Rolle, welches.
In Frühjahr 3.0 wird die Standardanmerkung ( JSR-330 ) unterstützt
@javax.inject.Inject
- verwenden Sie sie mit einer Kombination aus@Qualifier
. Beachten Sie, dass spring jetzt auch die@javax.inject.Qualifier
Meta-Annotation unterstützt:So können Sie haben
oder
Und dann:
Dies macht weniger Gebrauch von String-Namen, die falsch geschrieben werden können und schwieriger zu pflegen sind.
Was die ursprüngliche Frage betrifft: Beide führen ohne Angabe von Attributen der Annotation eine Injektion nach Typ durch. Der Unterschied ist:
@Resource
Mit dieser Option können Sie einen Namen für die injizierte Bean angeben@Autowired
ermöglicht es Ihnen, es als nicht obligatorisch zu markieren.quelle
foo
oder einen KonstruktorSomeBean
mit einemFoo
Parameter?@Resource
und@Autowired
, die tatsächliche Antwort ist die von @Ichthyo gepostete. Ich denke, diese muss aktualisiert werden.Beide
@Autowired
(oder@Inject
) und@Resource
funktionieren gleich gut. Aber es gibt einen konzeptuellen Unterschied oder einen Unterschied in der Bedeutung@Resource
bedeutet, mir eine bekannte Ressource mit Namen zu besorgen . Der Name wird aus dem Namen des mit Anmerkungen versehenen Setzers oder Felds extrahiert oder aus dem Namen-Parameter übernommen.@Inject
oder@Autowired
versuchen Sie, eine geeignete andere Komponente nach Typ zu verdrahten .Im Grunde sind dies also zwei ziemlich unterschiedliche Konzepte. Leider verfügt die Spring-Implementierung von
@Resource
über einen integrierten Fallback, der aktiviert wird, wenn die Auflösung nach Namen fehlschlägt. In diesem Fall wird auf die@Autowired
Artauflösung nach Art zurückgegriffen. Obwohl dieser Fallback praktisch ist, verursacht er@Resource
meiner Meinung nach viel Verwirrung, da die Leute sich des konzeptionellen Unterschieds nicht bewusst sind und ihn eher für typbasiertes Autowiring verwenden.quelle
@Resource
Anmerkungen versehenes Feld haben und der Feldname mit der ID einer Bean im Containerorg.springframework.beans.factory.BeanNotOfRequiredTypeException
übereinstimmt, wird Spring ausgelöst, wenn sich ihre Typen unterscheiden. Dies liegt daran, dass Beans zuerst nach Namen in@Resource
Anmerkungen und nicht nach Typ abgeglichen werden . Wenn der Name der Eigenschaft jedoch nicht mit dem Namen der Bean übereinstimmt, werden sie von Spring nach Typ verkabelt.@Autowire
kann und wird dies nicht funktionieren. Sie müssen@Resource
in diesem Fall verwenden.Der Hauptunterschied besteht darin, dass
@Autowired
es sich um eine Federanmerkung handelt. Während@Resource
wird vom JSR-250 spezifiziert, wie Sie selbst betont haben. Letzteres ist also Teil von Java, während Ersteres Frühlingsspezifisch 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 Übergang von einem Rahmen zu einem anderen wird als sehr unwahrscheinlich, wenn nicht als Mythos angesehen, insbesondere im Fall des Frühlings.quelle
@Autowired
mit@Qualifier
wirklich ist mächtiger als die JSR Standard@Resource
Annotation (man denke an optionalen Abhängigkeiten zum Beispiel mit@Autowired(required=false)
. Sie können das nicht mit@Resource
)Ich möchte einen Kommentar von @Jules zu dieser Antwort auf diese 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. Hier ist jedoch eine kurze Zusammenfassung seiner Nützlichkeit:
Wie wählen Anmerkungen die richtige Implementierung aus?
@Autowired
und@Inject
@Resource
Welche Anmerkungen (oder Kombinationen von) sollte ich zum Injizieren meiner Bohnen verwenden?
Benennen Sie Ihre Komponente explizit [@Component ("beanName")]
Verwendung
@Resource
mit demname
Attribut [@Resource (name = "beanName")]Warum sollte ich nicht verwenden
@Qualifier
?Vermeiden Sie
@Qualifier
Anmerkungen, es sei denn, Sie möchten eine Liste ähnlicher Beans erstellen. Beispielsweise möchten Sie möglicherweise eine Reihe von Regeln mit einer bestimmten@Qualifier
Anmerkung markieren . Dieser Ansatz macht es einfach, eine Gruppe von Regelklassen in eine Liste einzufügen, die zur Datenverarbeitung verwendet werden kann.Verlangsamt die Bohneninjektion mein Programm?
Scannen Sie bestimmte Pakete nach Komponenten
[context:component-scan base-package="com.sourceallies.person"]
. Dies führt zwar zu mehrcomponent-scan
Konfigurationen, verringert jedoch die Wahrscheinlichkeit, dass Sie Ihrem Spring-Kontext unnötige Komponenten hinzufügen.Referenz: Spring Injection mit @Resource, @Autowired und @Inject
quelle
Folgendes habe ich aus dem Spring 3.0.x-Referenzhandbuch erhalten : -
quelle
@Autowired + @Qualifier funktioniert nur mit Spring DI, wenn Sie in Zukunft einen anderen DI verwenden möchten. @Resource ist eine gute Option.
Ein weiterer Unterschied, den ich als sehr bedeutsam empfand, ist, dass @Qualifier keine dynamische Bean-Verkabelung unterstützt, da @Qualifier keine Platzhalter unterstützt, während @Resource dies sehr gut tut.
Zum Beispiel: Wenn Sie eine Schnittstelle mit mehreren Implementierungen wie dieser haben
Mit @Autowired & @Qualifier müssen Sie eine bestimmte untergeordnete Implementierung wie festlegen
Wenn Sie mit @Resource keinen Platzhalter bereitstellen, können Sie einen Platzhalter einfügen und eine Eigenschaftendatei verwenden, um eine bestimmte untergeordnete Implementierung wie zu injizieren
Dabei wird service.name in der Eigenschaftendatei als festgelegt
Hoffe das hilft jemandem :)
quelle
Beide sind gleich gut. Der Vorteil der Verwendung von Resource besteht in Zukunft darin, dass Ihre Codeänderungen viel einfacher sind, wenn Sie ein anderes DI-Framework als Spring verwenden möchten. Bei Verwendung von Autowired ist Ihr Code eng mit den Federn DI verbunden.
quelle
Wenn Sie die Basisklassen dieser beiden Anmerkungen kritisch analysieren, werden Sie die folgenden Unterschiede feststellen.
@Autowired
wird verwendetAutowiredAnnotationBeanPostProcessor
, um Abhängigkeiten einzufügen.@Resource
wird verwendetCommonAnnotationBeanPostProcessor
, um Abhängigkeiten einzufügen.Obwohl sie unterschiedliche Postprozessorklassen verwenden, verhalten sich alle nahezu identisch. Die Unterschiede liegen kritisch in ihren Ausführungspfaden, die ich unten hervorgehoben habe.
1. Übereinstimmungen nach Typ
2. Einschränkungen nach Qualifikationsmerkmalen
3. Übereinstimmungen nach Namen
1. Übereinstimmungen nach Namen
2. Übereinstimmungen nach Typ
3. Einschränkungen nach Qualifikationsmerkmalen (werden ignoriert, wenn Übereinstimmungen nach Namen gefunden werden)
quelle
Wenn
@Resource
Sie die Bean-Selbstinjektion durchführen können, ist dies möglicherweise erforderlich, um die gesamte zusätzliche Logik auszuführen, die von Bean-Postprozessoren wie Transaktions- oder sicherheitsrelevanten Dingen hinzugefügt wurde.Mit Spring 4.3+
@Autowired
ist dies auch möglich.quelle
@Resource
wird häufig von übergeordneten Objekten verwendet, die über JNDI definiert sind.@Autowired
oder@Inject
wird von allgemeineren Bohnen verwendet.Soweit ich weiß, handelt es sich weder um eine Spezifikation noch um eine Konvention. Es ist eher die logische Art und Weise, wie Standardcode diese Anmerkungen verwendet.
quelle
Als Hinweis hier:
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext
undSpringBeanAutowiringSupport.processInjectionBasedOnServletContext
funktioniert NICHT mit@Resource
Anmerkungen. Es gibt also Unterschiede.quelle