TL; DR
@Autowired annotation membuat Anda perlu melakukan pengkabelan sendiri dalam file XML (atau cara lain) dan hanya menemukan bagi Anda apa yang perlu disuntikkan di mana, dan melakukannya untuk Anda.
Penjelasan lengkap
The @Autowired
penjelasan memungkinkan Anda untuk melewatkan konfigurasi tempat lain apa untuk menyuntikkan dan hanya melakukannya untuk Anda. Dengan asumsi paket com.mycompany.movies
Anda adalah Anda harus meletakkan tag ini di XML (file konteks aplikasi) Anda:
<context:component-scan base-package="com.mycompany.movies" />
Tag ini akan melakukan pemindaian otomatis. Dengan asumsi setiap kelas yang harus menjadi kacang diberi penjelasan dengan penjelasan yang benar seperti @Component
(untuk kacang sederhana) atau @Controller
(untuk kontrol servlet) atau @Repository
(untuk DAO
kelas) dan kelas-kelas ini berada di suatu tempat di bawah paket com.mycompany.movies
, Spring akan menemukan semua ini dan membuat kacang untuk masing-masing. Ini dilakukan dalam 2 pemindaian kelas - pertama kali hanya mencari kelas yang perlu menjadi kacang dan memetakan injeksi yang perlu dilakukan, dan pada pemindaian kedua itu menyuntikkan kacang. Tentu saja, Anda dapat mendefinisikan kacang Anda dalam file XML yang lebih tradisional atau dengan kelas @Configuration (atau kombinasi ketiganya).
The @Autowired
penjelasan mengatakan musim semi di mana suntikan perlu terjadi. Jika Anda menaruhnya di atas metode, setMovieFinder
ia memahami (dengan awalan set
+ @Autowired
penjelasan) bahwa kacang perlu disuntikkan. Dalam pemindaian kedua, Spring mencari kacang jenis MovieFinder
, dan jika menemukan kacang seperti itu, ia menyuntikkannya ke metode ini. Jika menemukan dua kacang seperti itu, Anda akan mendapatkan Exception
. Untuk menghindarinya Exception
, Anda dapat menggunakan @Qualifier
anotasi dan memberi tahu yang mana dari kedua kacang yang akan disuntikkan dengan cara berikut:
@Qualifier("redBean")
class Red implements Color {
// Class code here
}
@Qualifier("blueBean")
class Blue implements Color {
// Class code here
}
Atau jika Anda lebih suka menyatakan kacang di XML Anda, itu akan terlihat seperti ini:
<bean id="redBean" class="com.mycompany.movies.Red"/>
<bean id="blueBean" class="com.mycompany.movies.Blue"/>
Dalam @Autowired
deklarasi, Anda juga perlu menambahkan @Qualifier
untuk memberi tahu yang mana dari dua kacang warna yang akan disuntikkan:
@Autowired
@Qualifier("redBean")
public void setColor(Color color) {
this.color = color;
}
Jika Anda tidak ingin menggunakan dua anotasi ( @Autowired
dan @Qualifier
) Anda dapat menggunakan @Resource
untuk menggabungkan keduanya:
@Resource(name="redBean")
public void setColor(Color color) {
this.color = color;
}
The @Resource
(Anda dapat membaca beberapa data tambahan tentang hal itu di komentar pertama pada jawaban ini) suku cadang Anda menggunakan dua penjelasan dan sebagai gantinya Anda hanya menggunakan satu.
Saya hanya akan menambahkan dua komentar lagi:
- Praktik yang baik akan digunakan
@Inject
bukan @Autowired
karena tidak spesifik Musim Semi dan merupakan bagian dari JSR-330
standar .
- Praktik bagus lainnya adalah meletakkan
@Inject
/ @Autowired
pada konstruktor alih-alih metode. Jika Anda meletakkannya di konstruktor, Anda dapat memvalidasi bahwa kacang yang disuntikkan tidak nol dan gagal cepat ketika Anda mencoba memulai aplikasi dan menghindari NullPointerException
ketika Anda benar-benar harus menggunakan kacang.
Pembaruan : Untuk melengkapi gambar, saya membuat pertanyaan baru tentang @Configuration
kelas.
MovieFinder
adalah Antarmuka, dan kami memiliki kacang untukMovieFinderImpl
(bean id = movieFinder), Spring akan otomatis menyuntikkannya berdasarkan jenis atau nama?@Qualifier
. Jika Anda - menurut nama, jika tidak - berdasarkan jenis. Berdasarkan jenis akan bekerja hanya jika Anda hanya memiliki satu jenis kacangMovieFinder
dalam konteks Anda. Lebih dari 1 akan menghasilkan pengecualian.@Autowired
anotasi padaprepare
metode pada Contoh 2 . Ini menginisialisasiMovieRecommender
tetapi, secara teknis, BUKAN setter.@Autowired
juga berfungsi untuk konstruktor. Ia menemukan dependensi yang diperlukan dan menyuntikkannya ke konstruktor.Tidak ada dalam contoh mengatakan bahwa "kelas mengimplementasikan antarmuka yang sama".
MovieCatalog
adalah tipe danCustomerPreferenceDao
tipe lain. Musim semi dapat dengan mudah membedakan mereka.Pada Musim Semi 2.x, kabel biji sebagian besar terjadi melalui ID kacang atau nama. Ini masih didukung oleh Spring 3.x tetapi sering kali, Anda akan memiliki satu contoh kacang dengan jenis tertentu - sebagian besar layanan adalah lajang. Membuat nama untuk itu membosankan. Jadi Spring mulai mendukung "autowire by type".
Apa yang ditunjukkan contoh adalah berbagai cara yang dapat Anda gunakan untuk menyuntikkan kacang ke dalam bidang, metode, dan konstruktor.
XML sudah berisi semua informasi yang dibutuhkan Spring karena Anda harus menentukan nama kelas yang sepenuhnya memenuhi syarat di setiap kacang. Anda harus sedikit berhati-hati dengan antarmuka, meskipun:
Autowiring ini akan gagal:
Karena Java tidak menyimpan nama parameter dalam kode byte, Spring tidak dapat membedakan antara dua kacang lagi. Cara mengatasinya adalah dengan menggunakan
@Qualifier
:sumber
prepare
, parameter mana yang akan digunakan untuk memanggil fungsi ini?@Autowired
bidang disuntikkan. Pegas kemudian akan melihat bahwa parameter diperlukan dan akan menggunakan aturan yang sama yang digunakan untuk injeksi lapangan untuk menemukan parameter.Ya, Anda dapat mengonfigurasi file xml konteks servlet Spring untuk menetapkan kacang Anda (yaitu, kelas), sehingga dapat melakukan injeksi otomatis untuk Anda. Namun, harap dicatat, bahwa Anda harus melakukan konfigurasi lain untuk menjalankan dan menjalankan Spring dan cara terbaik untuk melakukannya, adalah dengan mengikuti tutorial ke atas.
Setelah Musim Semi Anda dikonfigurasi mungkin, Anda dapat melakukan hal berikut dalam file xml konteks Musim Semi servlet Anda untuk Contoh 1 di atas untuk bekerja (harap ganti nama paket com.movies dengan apa nama paket yang sebenarnya dan jika ini adalah pihak ke-3 kelas, maka pastikan file jar yang sesuai ada di classpath):
atau jika kelas MovieFinder memiliki konstruktor dengan nilai primitif, maka Anda bisa seperti ini,
atau jika kelas MovieFinder memiliki konstruktor yang mengharapkan kelas lain, maka Anda bisa melakukan sesuatu seperti ini,
... di mana ' otherBeanRef ' adalah kacang lain yang memiliki referensi ke kelas yang diharapkan.
sumber
@Autowired