Bagaimana Spring autowire dengan nama ketika lebih dari satu kacang yang cocok ditemukan?

106

Misalkan saya memiliki antarmuka seperti ini:

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

Dan cuplikan konfigurasi xml ini:

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

Bagaimana cara mengontrol dependensi yang dipasangi otomatis di bawah ini? Saya mau yang Inggris.

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

Saya menggunakan Spring 3.0.3.RELEASE.

Maniganda Prakash
sumber
Saya pikir saya akan menambahkan bahwa saya mendapatkan "Tidak ada jenis kacang unik ..." dalam satu lingkungan (pengujian) dan bekerja dengan baik di lingkungan pengembangan saya. Saya yakin itu semacam classpath, tetapi ternyata, jika Anda menambahkan @Qualifier, itu berfungsi dengan baik.
markthegrea

Jawaban:

113

Ini didokumentasikan di bagian 3.9.3 dari manual Spring 3.0:

Untuk pertandingan fallback, nama kacang dianggap sebagai nilai kualifikasi default.

Dengan kata lain, perilaku default seolah-olah Anda menambahkan @Qualifier("country")ke metode penyetel.

skaffman
sumber
Saat Anda mengatakan "nama kacang", apakah yang Anda maksud adalah nama bidang yang akan berisi kacang? (Yaitu dalam kasus ini country)
Gugatan Dana Monica
67

Anda dapat menggunakan anotasi @Qualifier

Dari sini

Menyempurnakan pengiriman otomatis berbasis anotasi dengan kualifikasi

Karena autowiring menurut jenis dapat menghasilkan banyak kandidat, seringkali diperlukan kontrol lebih besar atas proses seleksi. Salah satu cara untuk melakukannya adalah dengan anotasi @Qualifier Spring. Hal ini memungkinkan untuk mengaitkan nilai qualifier dengan argumen tertentu, mempersempit himpunan tipe yang cocok sehingga kacang tertentu dipilih untuk setiap argumen. Dalam kasus yang paling sederhana, ini bisa menjadi nilai deskriptif biasa:

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

Ini akan menggunakan Inggris menambahkan id ke kacang USA dan menggunakannya jika Anda menginginkan USA.

Paul Whelan
sumber
12

Cara lain untuk mendapatkan hasil yang sama adalah dengan menggunakan anotasi @Value:

public class Main {
     private Country country;

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

Dalam kasus ini, "#{country}string adalah ekspresi Spring Expression Language (SpEL) yang mengevaluasi kacang bernama country.

Ricardo Veguilla
sumber
bisakah itu disuntikkan berdasarkan properti? bagaimana jika USA atau UK adalah semacam parameter yang berasal dari URL dan saya ingin memasukkan 2 hal berbeda berdasarkan parameternya?
Kalpesh Soni
6

Satu lagi solusi dengan menyelesaikan dengan nama:

@Resource(name="country")

Ini menggunakan paket javax.annotation , jadi ini bukan khusus Spring, tetapi Spring mendukungnya.

tema
sumber
1
tetapi @Resourcetidak akan keluar-of-the-box dengan java 11 karena modul jigsaw
Dirk Hoffmann