Pertama, dan yang paling penting - semua kacang Spring dikelola - mereka "hidup" di dalam wadah, yang disebut "konteks aplikasi".
Kedua, setiap aplikasi memiliki titik masuk ke konteks itu. Aplikasi web memiliki Servlet, JSF menggunakan el-resolver, dll. Juga, ada tempat di mana konteks aplikasi di-bootstrap dan semua kacang - otomatis. Dalam aplikasi web ini bisa menjadi pendengar startup.
Autowiring terjadi dengan menempatkan sebuah instance dari satu kacang ke dalam bidang yang diinginkan dalam sebuah instance dari kacang lain. Kedua kelas harus kacang, yaitu mereka harus didefinisikan untuk hidup dalam konteks aplikasi.
Apa yang "hidup" dalam konteks aplikasi? Ini berarti bahwa konteksnya instantiates objek, bukan Anda. Yaitu - Anda tidak pernah membuat new UserServiceImpl()
- wadah menemukan setiap titik injeksi dan menetapkan contoh di sana.
Di pengontrol Anda, Anda hanya memiliki yang berikut ini:
@Controller // Defines that this class is a spring bean
@RequestMapping("/users")
public class SomeController {
// Tells the application context to inject an instance of UserService here
@Autowired
private UserService userService;
@RequestMapping("/login")
public void login(@RequestParam("username") String username,
@RequestParam("password") String password) {
// The UserServiceImpl is already injected and you can use it
userService.login(username, password);
}
}
Beberapa catatan:
- Dalam Anda
applicationContext.xml
Anda harus mengaktifkan <context:component-scan>
sehingga kelas-scan untuk @Controller
, @Service
, dll penjelasan.
- Titik masuk untuk aplikasi Spring-MVC adalah DispatcherServlet, tetapi tersembunyi dari Anda, dan karenanya interaksi langsung dan bootstrap konteks aplikasi terjadi di belakang layar.
UserServiceImpl
juga harus didefinisikan sebagai kacang - baik menggunakan <bean id=".." class="..">
atau menggunakan @Service
anotasi. Karena itu akan menjadi satu-satunya implementor UserService
, itu akan disuntikkan.
- Terlepas dari
@Autowired
anotasi, Spring dapat menggunakan autowiring yang dapat dikonfigurasi dengan XML. Dalam hal itu, semua bidang yang memiliki nama atau tipe yang cocok dengan kacang yang ada secara otomatis mendapatkan kacang disuntikkan. Bahkan, itu adalah ide awal autowiring - untuk memiliki bidang yang disuntikkan dengan dependensi tanpa konfigurasi apa pun. Anotasi lain seperti @Inject
, @Resource
juga bisa digunakan.
Tergantung pada apakah Anda ingin rute penjelasan atau rute definisi XML kacang.
Katakanlah Anda sudah mendefinisikan kacang di
applicationContext.xml
:Autowiring terjadi ketika aplikasi dijalankan. Jadi, di
fooController
, yang demi argumen ingin menggunakanUserServiceImpl
kelas, Anda akan memberi anotasi sebagai berikut:Saat dilihat
@Autowired
, Spring akan mencari kelas yang cocok dengan properti diapplicationContext
, dan menyuntikkannya secara otomatis. Jika Anda memiliki lebih dari satuUserService
kacang, maka Anda harus memenuhi syarat kacang mana yang harus digunakan.Jika Anda melakukan hal berikut:
Ini tidak akan mengambil
@Autowired
kecuali Anda mengaturnya sendiri.sumber
bean id
diapplicationContext.xml
. Kita harus mendefinisikanuserService
variabel denganUserService
tipe. Jadi mengapa membuat entri dalamxml
file.@Autowired
adalah anotasi yang diperkenalkan di Spring 2.5, dan hanya digunakan untuk injeksi.Sebagai contoh:
sumber
@Autowired
tidak berarti bahwa "Anda dapat menggunakan semua fungsi (metode) dan variabel dalamB
kelas dari kelasA
". Apa yang dilakukannya adalah membawa sebuah contoh dariA
ke contohB
, sehingga Anda dapat melakukana.getId()
dariB
.Bagaimana cara
@Autowired
kerjanya secara internal?Contoh:
File .xml akan terlihat sama jika tidak menggunakan
@Autowired
:Jika Anda menggunakan
@Autowired
itu:File .xml akan terlihat sama jika tidak menggunakan
@Autowired
:Jika masih ada keraguan, silakan ikuti demo langsung di bawah ini
Bagaimana cara @Autowired bekerja secara internal?
sumber
Anda hanya perlu membubuhi keterangan kelas layanan Anda
UserServiceImpl
dengan anotasi:Kontainer pegas akan menjaga siklus hidup kelas ini saat mendaftar sebagai layanan.
Kemudian pada pengontrol Anda, Anda dapat secara otomatis mengirim (instantiate) dan menggunakan fungsinya:
sumber
Injeksi ketergantungan pegas membantu Anda menghapus kopling dari kelas Anda. Alih-alih membuat objek seperti ini:
Anda akan menggunakan ini setelah memperkenalkan DI:
Untuk mencapai ini, Anda perlu membuat kacang layanan Anda di
ServiceConfiguration
file Anda . Setelah itu Anda perlu mengimporServiceConfiguration
kelas itu keWebApplicationConfiguration
kelas Anda sehingga Anda dapat autowire kacang itu ke Controller Anda seperti ini:Anda dapat menemukan contoh POC berbasis konfigurasi java di sini .
sumber
Cara standar:
Antarmuka layanan pengguna:
Kelas UserServiceImpl:
Keluaran:
Example test UserServiceImpl
Itu adalah contoh yang bagus dari kelas berpasangan ketat, contoh desain yang buruk dan akan ada masalah dengan pengujian (PowerMockito juga buruk).
Sekarang mari kita lihat injeksi ketergantungan SpringBoot, contoh yang bagus dari kopling longgar:
Antarmuka tetap sama,
Kelas utama:
Kelas ServiceUserImpl:
Keluaran:
Example test UserServiceImpl
dan sekarang mudah untuk menulis tes:
Saya menunjukkan
@Autowired
anotasi pada konstruktor tetapi juga dapat digunakan pada setter atau bidang.sumber
Seluruh konsep inversi kontrol berarti Anda bebas dari tugas untuk membuat instance objek secara manual dan memberikan semua dependensi yang diperlukan. Ketika Anda memberi anotasi pada kelas dengan anotasi yang sesuai (mis.
@Service
Spring akan secara otomatis membuat objek untuk Anda. Jika Anda tidak terbiasa dengan anotasi, Anda juga dapat menggunakan file XML. Namun, itu bukan ide yang buruk untuk membuat instance kelas secara manual (dengannew
kata kunci) dalam unit test ketika Anda tidak ingin memuat seluruh konteks pegas.sumber
Ingatlah bahwa Anda harus mengaktifkan
@Autowired
anotasi dengan menambahkan elemen<context:annotation-config/>
ke dalam file konfigurasi pegas. Ini akan mendaftarAutowiredAnnotationBeanPostProcessor
yang menangani pemrosesan anotasi.Dan kemudian Anda dapat autowire layanan Anda dengan menggunakan metode injeksi lapangan.
Saya menemukan ini dari pos Spring @autowired annotation
sumber
Ada 3 cara Anda bisa membuat instance menggunakan
@Autowired
.1.
@Autowired
pada PropertiesAnotasi dapat digunakan langsung pada properti, sehingga menghilangkan kebutuhan getter dan setter:
Dalam contoh di atas, Spring mencari dan menyuntikkan
userService
saatUserController
dibuat.2.
@Autowired
tentang SetterThe
@Autowired
anotasi dapat digunakan pada metode setter. Dalam contoh di bawah ini, ketika anotasi digunakan pada metode setter, metode setter dipanggil dengan instanceuserService
kapanUserController
dibuat:3.
@Autowired
tentang KonstruktorThe
@Autowired
penjelasan juga dapat digunakan pada konstruktor. Dalam contoh di bawah ini, ketika anotasi digunakan pada konstruktor, turunanuserService
disuntikkan sebagai argumen ke konstruktor saatUserController
dibuat:sumber
Dengan kata-kata sederhana Autowiring, tautan kabel secara otomatis, kini muncul pertanyaan siapa yang melakukan ini dan jenis kabel apa. Jawabannya adalah: Kontainer melakukan ini dan jenis kabel sekunder didukung, primitif perlu dilakukan secara manual.
Pertanyaan: Bagaimana wadah tahu jenis kabel apa?
Jawaban: Kami mendefinisikannya sebagai byType, byName, constructor.
Pertanyaan: Apakah ada cara kita tidak mendefinisikan jenis autowiring?
Jawab: Ya, ada di sana dengan melakukan satu anotasi, @Autowired.
Pertanyaan: Tetapi bagaimana sistem tahu, saya harus memilih jenis data sekunder?
Jawaban: Anda akan memberikan data itu dalam file spring.xml Anda atau dengan menggunakan anotasi sterotype ke kelas Anda sehingga wadah itu sendiri dapat membuat objek untuk Anda.
sumber