Wie verdrahtet Spring automatisch nach Namen, wenn mehr als eine passende Bohne gefunden wird?

106

Angenommen, ich habe Schnittstellen wie diese:

interface Country {}
class USA implements Country {}
class UK implements Country ()

Und dieser Ausschnitt aus der Konfigurations-XML:

<bean class="USA"/>
<bean id="country" class="UK"/>
<bean id="main" class="Main"/>

Wie kann ich steuern, welche Abhängigkeit unten automatisch verdrahtet wird? Ich hätte gerne die in Großbritannien.

class Main {
    private Country country;
    @Autowired
    public void setCountry(Country country) {
        this.country = country;
    }
}

Ich benutze Spring 3.0.3.RELEASE.

Maniganda Prakash
quelle
Ich dachte, ich würde hinzufügen, dass ich in einer (Test-) Umgebung eine "Keine eindeutige Bohne vom Typ ..." bekommen habe und es in meiner Entwicklungsumgebung gut funktioniert hat. Ich bin mir sicher, dass es eine Art Klassenpfad war, aber es stellte sich heraus, dass es gut funktioniert hat, wenn Sie den @Qualifier hinzufügen.
Märzhegrea

Antworten:

113

Dies ist in Abschnitt 3.9.3 des Spring 3.0-Handbuchs dokumentiert:

Bei einer Fallback-Übereinstimmung wird der Bean-Name als Standardqualifizierungswert betrachtet.

Mit anderen Worten, das Standardverhalten ist so, als hätten Sie @Qualifier("country")der Setter-Methode hinzugefügt .

Skaffman
quelle
Wenn Sie "Bean-Name" sagen, meinen Sie damit den Namen des Feldes, das die Bean enthalten soll? (dh in diesem Fall country)
Fund Monica Klage
67

Sie können die Annotation @Qualifier verwenden

Von hier aus

Feinabstimmung der annotationsbasierten automatischen Verdrahtung mit Qualifikationsmerkmalen

Da die automatische Verdrahtung nach Typ zu mehreren Kandidaten führen kann, ist es häufig erforderlich, mehr Kontrolle über den Auswahlprozess zu haben. Eine Möglichkeit, dies zu erreichen, ist die Annotation @Qualifier von Spring. Auf diese Weise können Qualifikationswerte bestimmten Argumenten zugeordnet werden, wodurch die Menge der Typübereinstimmungen eingegrenzt wird, sodass für jedes Argument eine bestimmte Bean ausgewählt wird. Im einfachsten Fall kann dies ein einfacher beschreibender Wert sein:

class Main {
    private Country country;
    @Autowired
    @Qualifier("country")
    public void setCountry(Country country) {
        this.country = country;
    }
}

Dies wird in Großbritannien verwendet. Fügen Sie der USA-Bean eine ID hinzu, und verwenden Sie diese, wenn Sie die USA möchten.

Paul Whelan
quelle
12

Eine andere Möglichkeit, dasselbe Ergebnis zu erzielen, ist die Verwendung der Annotation @Value:

public class Main {
     private Country country;

     @Autowired
     public void setCountry(@Value("#{country}") Country country) {
          this.country = country;
     }
}

In diesem Fall ist die "#{country}Zeichenfolge ein SpEL- Ausdruck (Spring Expression Language) , der als Bean mit dem Namen ausgewertet wird country.

Ricardo Veguilla
quelle
Kann das basierend auf dem Eigentum injiziert werden? Was ist, wenn USA oder UK ein Parameter ist, der von der URL stammt, und ich zwei verschiedene Dinge basierend auf dem Parameter einfügen möchte?
Kalpesh Soni
6

Eine weitere Lösung mit Namensauflösung:

@Resource(name="country")

Es verwendet das Paket javax.annotation , ist also nicht Spring-spezifisch, aber Spring unterstützt es.

Thema
quelle
1
aber @Resourcewird nicht mit Java 11 aufgrund von Puzzle-Modulen sofort einsatzbereit sein
Dirk Hoffmann