Come fa Spring autowire per nome quando viene trovato più di un bean corrispondente?


106

Supponiamo che io abbia interfacce come queste:

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

E questo frammento di configurazione xml:

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

Come posso controllare quale dipendenza è autowired di seguito? Vorrei quello britannico.

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

Sto usando Spring 3.0.3.RELEASE.


Ho pensato di aggiungere che stavo ottenendo un "Nessun bean di tipo unico ..." in un ambiente (di prova) e ha funzionato bene nel mio ambiente di sviluppo. Sono sicuro che fosse una sorta di classpath, ma si è scoperto che, se aggiungi @Qualifier, ha funzionato bene.
markthegrea

Risposte:


113

Ciò è documentato nella sezione 3.9.3 del manuale Spring 3.0:

Per una corrispondenza di fallback, il nome del bean è considerato un valore del qualificatore predefinito.

In altre parole, il comportamento predefinito è come se avessi aggiunto @Qualifier("country")al metodo setter.


Quando dici "nome fagiolo", intendi il nome del campo che conterrà il fagiolo? (cioè in questo caso country)
Finanzia la causa di Monica il

67

Puoi utilizzare l'annotazione @Qualifier

Da qui

Ottimizzazione del cablaggio automatico basato sull'annotazione con qualificatori

Poiché l'autowiring per tipo può portare a più candidati, è spesso necessario avere un maggiore controllo sul processo di selezione. Un modo per farlo è con l'annotazione @Qualifier di Spring. Ciò consente di associare i valori dei qualificatori con argomenti specifici, restringendo l'insieme di corrispondenze di tipo in modo che venga scelto un bean specifico per ogni argomento. Nel caso più semplice, questo può essere un semplice valore descrittivo:

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

Questo userà il Regno Unito per aggiungere un ID al bean USA e usarlo se vuoi gli USA.


12

Un altro modo per ottenere lo stesso risultato è utilizzare l'annotazione @Value:

public class Main {
     private Country country;

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

In questo caso, la "#{country}stringa è un'espressione SpEL (Spring Expression Language) che restituisce un bean denominato country.


può essere iniettato in base alla proprietà? cosa succede se USA o UK è una sorta di parametro proveniente dall'URL e voglio iniettare 2 cose diverse in base a ciò che è il parametro?
Kalpesh Soni

6

Un'altra soluzione con la risoluzione per nome:

@Resource(name="country")

Usa il pacchetto javax.annotation , quindi non è specifico per Spring, ma Spring lo supporta.


1
ma @Resourcenon ci sarà immediatamente con Java 11 a causa dei moduli jigsaw
Dirk Hoffmann

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.