Spring: Mengapa kita autowire antarmuka dan bukan kelas yang diimplementasikan?

142

Contoh

interface IA
{
  public void someFunction();
}

@Resource(name="b")
class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}

@Resource(name="c")
class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

class MyRunner
{

  @Autowire
  @Qualifier("b") 
  IA worker;

  worker.someFunction();
}

Adakah yang bisa menjelaskan hal ini kepada saya?

  • Bagaimana pegas tahu tipe polimorfik mana yang digunakan.
  • Apakah saya perlu @Qualifieratau tidak @Resource?
  • Mengapa kita autowire antarmuka dan bukan kelas yang diimplementasikan?
stackoverflow
sumber
10
Anda autowire antarmuka sehingga Anda bisa menghubungkan implementasi yang berbeda - itulah salah satu poin pengkodean ke antarmuka, bukan kelas.
Dave Newton
Anda menghubungkan implementasi yang berbeda; Saya tidak mengerti pertanyaannya.
Dave Newton
Jika kita menggunakan kabel di antarmuka, apa yang terjadi ketika ada metode visibilitas default dalam kelas Impl yang saya perlu akses? Saya tidak dapat menambahkan metode rintisan ke antarmuka karena Antarmuka publik tidak dapat berisi pengubah standar.
jlewkovich
Kemungkinan duplikat Spring Autowiring class vs interface?
OhadR
1
Saya pikir membuat antarmuka hanya untuk satu implementasi adalah praktik bodoh yang diterima di dunia java. Hasilnya adalah banyak kode sampah, tetapi semua orang senang bahwa mereka mengikuti aturan SOLID dan OOP. Gunakan guice dan buang pegas ke tempat sampah sejarah.
avgolubev

Jawaban:

224

Bagaimana pegas tahu tipe polimorfik mana yang digunakan.

Selama hanya ada satu implementasi antarmuka dan implementasi itu dijelaskan dengan @Componentpemindaian komponen Spring diaktifkan, kerangka kerja Spring dapat mengetahui pasangan (antarmuka, implementasi). Jika pemindaian komponen tidak diaktifkan, maka Anda harus mendefinisikan kacang secara eksplisit di aplikasi-config.xml Anda (atau file konfigurasi pegas yang setara).

Apakah saya memerlukan @Qualifier atau @Resource?

Setelah Anda memiliki lebih dari satu implementasi, maka Anda harus memenuhi syarat masing-masing dan selama pengkabelan otomatis, Anda perlu menggunakan @Qualifieranotasi untuk menyuntikkan implementasi yang tepat, bersama dengan @Autowiredanotasi. Jika Anda menggunakan @Resource (semantik J2EE), maka Anda harus menentukan nama bean menggunakan nameatribut anotasi ini.

Mengapa kita autowire antarmuka dan bukan kelas yang diimplementasikan?

Pertama, selalu merupakan praktik yang baik untuk kode ke antarmuka secara umum. Kedua, dalam hal pegas, Anda dapat menyuntikkan implementasi apa pun saat runtime. Kasus penggunaan yang umum adalah untuk menyuntikkan implementasi tiruan selama tahap pengujian.

interface IA
{
  public void someFunction();
}


class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}


class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

class MyRunner
{
     @Autowire
     @Qualifier("b") 
     IA worker;

     ....
     worker.someFunction();
}

Konfigurasi kacang Anda akan terlihat seperti ini:

<bean id="b" class="B" />
<bean id="c" class="C" />
<bean id="runner" class="MyRunner" />

Atau, jika Anda mengaktifkan pemindaian komponen pada paket yang ada, maka Anda harus memenuhi syarat setiap kelas dengan @Componentsebagai berikut:

interface IA
{
  public void someFunction();
}

@Component(value="b")
class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}


@Component(value="c")
class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

@Component    
class MyRunner
{
     @Autowire
     @Qualifier("b") 
     IA worker;

     ....
     worker.someFunction();
}

Kemudian workerdi MyRunnerakan disuntik dengan sebuah instance dari tipe B.

Vikdor
sumber
@stackoverflow Mengedit pertanyaan tidak masuk akal, kode baru termasuk dalam jawabannya. Kalau tidak, pertanyaan itu tidak masuk akal, karena akan menjawab sendiri.
Dave Newton
Vikdor - silakan lihat edit. Apakah itu cara yang benar untuk membubuhi keterangan kelas dan menyuntikkan objek?
stackoverflow
1
@VictorDombrovsky Apakah @Autowired @Qualifier("a1") a;valid?
Lucky
1
@ Beruntung saya melakukan kesalahan. Maksud saya@Autowired @Qualifier("a1") A a;
Victor Dombrovsky
1
Anda bahkan dapat menggunakan @Profile pada implementasi untuk mengontrol implementasi mana yang harus disuntikkan untuk antarmuka itu melalui argumen program atau properti aplikasi.
B15