Die Spring @ Qualifier-Anmerkung

1. Übersicht

In diesem Artikel werden wir untersuchen, bei welchen Annotationen @Qualifier uns helfen kann , welche Probleme sie lösen und wie sie verwendet werden.

Wir werden auch erklären, wie es sich von der Annotation @Primary und vom automatischen Verdrahten nach Namen unterscheidet.

2. Autowire-Bedarf an Begriffsklärung

Die Annotation @Autowired ist eine hervorragende Möglichkeit, die Notwendigkeit, eine Abhängigkeit in Spring einzufügen, explizit zu machen. Und obwohl es nützlich ist, gibt es Anwendungsfälle, für die diese Anmerkung allein Spring nicht ausreicht, um zu verstehen, welche Bean injiziert werden soll.

Standardmäßig löst Spring automatisch verdrahtete Einträge nach Typ auf.

Wenn mehr als eine Bean desselben Typs im Container verfügbar ist, löst das Framework die NoUniqueBeanDefinitionException aus , die angibt, dass mehr als eine Bean für die automatische Verdrahtung verfügbar ist.

Stellen wir uns eine Situation vor, in der es zwei mögliche Kandidaten für Spring gibt, die in einem bestimmten Fall als Bean-Kollaborateure eingesetzt werden können:

@Component("fooFormatter") public class FooFormatter implements Formatter { public String format() { return "foo"; } } @Component("barFormatter") public class BarFormatter implements Formatter { public String format() { return "bar"; } } @Component public class FooService { @Autowired private Formatter formatter; }

Wenn wir versuchen, FooService in unseren Kontext zu laden, löst das Spring-Framework eine NoUniqueBeanDefinitionException aus . Dies liegt daran, dass Spring nicht weiß, welche Bohne injiziert werden soll . Um dieses Problem zu vermeiden, gibt es verschiedene Lösungen. Die Annotation @Qualifier ist eine davon.

3. @Qualifier Annotation

Mithilfe der Annotation @Qualifier können wir das Problem beseitigen, welche Bean injiziert werden muss .

Schauen wir uns unser vorheriges Beispiel noch einmal an und sehen wir, wie wir das Problem lösen, indem wir die Annotation @Qualifier einfügen, um anzugeben, welche Bean wir verwenden möchten:

public class FooService { @Autowired @Qualifier("fooFormatter") private Formatter formatter; }

Durch Einfügen der Annotation @Qualifier zusammen mit dem Namen der spezifischen Implementierung, die wir verwenden möchten - in diesem Beispiel Foo - können wir Mehrdeutigkeiten vermeiden, wenn Spring mehrere Beans desselben Typs findet.

Wir müssen berücksichtigen, dass der zu verwendende Qualifizierername der in der Annotation @Component deklarierte ist .

Beachten Sie, dass wir auch die verwendet haben könnte @Qualifier Anmerkung auf den Formatter implementierenden Klassen, statt die Namen in ihrer Angabe @Component Anmerkungen, um den gleichen Effekt zu erzielen:

@Component @Qualifier("fooFormatter") public class FooFormatter implements Formatter { //... } @Component @Qualifier("barFormatter") public class BarFormatter implements Formatter { //... } 

4. @Qualifier vs @Primary

Es gibt eine weitere Anmerkung namens @Primary , mit der wir entscheiden können, welche Bean injiziert werden soll, wenn Unklarheiten hinsichtlich der Abhängigkeitsinjektion vorliegen.

Diese Anmerkung definiert eine Präferenz, wenn mehrere Beans desselben Typs vorhanden sind . Sofern nicht anders angegeben, wird die der Annotation @Primary zugeordnete Bean verwendet.

Sehen wir uns ein Beispiel an:

@Configuration public class Config { @Bean public Employee johnEmployee() { return new Employee("John"); } @Bean @Primary public Employee tonyEmployee() { return new Employee("Tony"); } }

In diesem Beispiel geben beide Methoden denselben Mitarbeitertyp zurück . Die Bean, die Spring injiziert, wird von der Methode tonyEmployee zurückgegeben . Dies liegt daran, dass es die Annotation @Primary enthält . Diese Anmerkung ist nützlich, wenn Sie angeben möchten , welche Bean eines bestimmten Typs standardmäßig eingefügt werden soll .

Und falls wir die andere Bohne an einem Injektionspunkt benötigen, müssen wir sie speziell angeben. Dies können wir über die Annotation @Qualifier tun . Beispielsweise könnten wir mithilfe der Annotation @Qualifier angeben, dass wir die von der johnEmployee- Methode zurückgegebene Bean verwenden möchten .

Es ist erwähnenswert, dass , wenn sowohl die @Qualifier und @Primary Anmerkungen vorhanden sind, dann ist die @Qualifier Anmerkung Vorrang haben. Grundsätzlich definiert @Primary einen Standard, während @Qualifier sehr spezifisch ist.

Sehen wir uns eine andere Möglichkeit an, die Annotation @Primary zu verwenden , diesmal anhand des ersten Beispiels:

@Component @Primary public class FooFormatter implements Formatter { //... } @Component public class BarFormatter implements Formatter { //... } 

In diesem Fall wird die Annotation @Primary in eine der implementierenden Klassen eingefügt und das Szenario wird eindeutig.

5. @Qualifier vs Autowiring nach Namen

Eine andere Möglichkeit, sich beim automatischen Verdrahten zwischen mehreren Beans zu entscheiden, besteht darin, den Namen des zu injizierenden Feldes zu verwenden. Dies ist die Standardeinstellung, falls für Spring keine weiteren Hinweise vorhanden sind . Sehen wir uns einen Code an, der auf unserem ersten Beispiel basiert:

public class FooService { @Autowired private Formatter fooFormatter; }

In diesem Fall bestimmt Spring, dass die zu injizierende Bean die FooFormatter- Bean ist, da der Feldname mit dem Wert übereinstimmt, den wir in der @ Component- Annotation für diese Bean verwendet haben.

6. Fazit

Wir haben die Szenarien beschrieben, in denen wir unterscheiden müssen, welche Bohnen injiziert werden sollen. Insbesondere haben wir die Annotation @Qualifier beschrieben und mit anderen ähnlichen Methoden verglichen, um zu bestimmen, welche Beans verwendet werden müssen.

Wie üblich ist der vollständige Code für diesen Artikel auf GitHub verfügbar.