Suntikan Pembina pada Musim Bunga dengan Lombok

1. Pengenalan

Lombok adalah perpustakaan yang sangat berguna mengatasi kod plat boiler. Sekiranya anda belum mengenalinya, saya sangat mengesyorkan untuk melihat tutorial sebelumnya - Pengenalan Projek Lombok.

Dalam artikel ini, kami akan menunjukkan kegunaannya bila digabungkan dengan Suntikan Dependensi Berasaskan Konstruktor Spring .

2. Suntikan Ketergantungan Berasaskan Konstruktor

Kaedah yang baik untuk menggantungkan kebergantungan pada musim bunga menggunakan Dependency Injection berasaskan c onstructor . Pendekatan ini memaksa kita untuk menyampaikan ketergantungan komponen secara eksplisit kepada konstruktor.

Berbanding dengan Suntikan Dependensi Berasaskan Lapangan , ia juga memberikan sejumlah kelebihan:

  • tidak perlu membuat komponen konfigurasi khusus ujian - kebergantungan disuntikkan secara eksplisit dalam konstruktor
  • reka bentuk yang konsisten - semua kebergantungan yang diperlukan ditekankan dan dijaga oleh definisi pembina
  • ujian unit sederhana - mengurangkan overhead Spring Framework
  • menuntut kebebasan menggunakan kata kunci akhir

Walau bagaimanapun, kerana keperluan untuk menulis konstruktor, ia digunakan untuk membawa kepada asas kod yang jauh lebih besar. Pertimbangkan dua contoh GreetingService dan FarewellService:

@Component public class GreetingService { @Autowired private Translator translator; public String produce() { return translator.translate("hello"); } }
@Component public class FarewellService { private final Translator translator; public FarewellService(Translator translator) { this.translator = translator; } public String produce() { return translator.translate("bye"); } }

Pada asasnya, kedua-dua komponen melakukan perkara yang sama - mereka memanggil Penterjemah yang boleh dikonfigurasi dengan kata khusus tugas.

Variasi kedua, bagaimanapun, lebih kabur kerana plat pemanas pembangun yang tidak benar-benar membawa nilai pada kod tersebut.

Dalam keluaran Spring terbaru, konstruktornya tidak perlu diberi penjelasan dengan anotasi @Autowired .

3. Suntikan Konstruktor Dengan Lombok

Dengan Lombok , mungkin untuk menghasilkan konstruktor untuk semua bidang kelas (dengan @AllArgsConstructor ) atau semua medan kelas akhir (dengan @RequiredArgsConstructor ). Lebih-lebih lagi, jika anda masih memerlukan konstruktor kosong, anda boleh menambahkan anotasi @NoArgsConstructor tambahan .

Mari buat komponen ketiga, serupa dengan dua sebelumnya:

@Component @RequiredArgsConstructor public class ThankingService { private final Translator translator; public String produce() { return translator.translate("thank you"); } }

Anotasi di atas akan menyebabkan Lombok menghasilkan konstruktor untuk kami:

@Component public class ThankingService { private final Translator translator; public String thank() { return translator.translate("thank you"); } /* Generated by Lombok */ public ThankingService(Translator translator) { this.translator = translator; } }

4. Pelbagai Pembina

Pembina tidak perlu diberi penjelasan selagi hanya ada satu komponen dan Spring secara pasti dapat memilihnya sebagai yang tepat untuk membuat objek baru. Setelah ada lebih banyak, anda juga perlu memberi penjelasan yang akan digunakan oleh wadah IoC.

Pertimbangkan contoh ApologizeService :

@Component @RequiredArgsConstructor public class ApologizeService { private final Translator translator; private final String message; @Autowired public ApologizeService(Translator translator) { this(translator, "sorry"); } public String produce() { return translator.translate(message); } }

Komponen di atas dapat dikonfigurasi secara opsional dengan bidang pesan yang tidak dapat berubah setelah komponen dibuat (oleh itu kekurangan setter ) Oleh itu ia memerlukan kami untuk menyediakan dua pengeluar - satu dengan konfigurasi penuh dan yang lain dengan nilai yang tersirat, lalai daripada mesej .

Kecuali salah satu pembangun diberi penjelasan dengan @Autowired , @Inject atau @Resource , Spring akan menimbulkan ralat:

Failed to instantiate [...]: No default constructor found;

Sekiranya kita ingin memberi penjelasan kepada konstruktor yang dihasilkan oleh Lombok , kita harus meneruskan penjelasan dengan parameter onConstructor dari @AllArgsConstructor :

@Component @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class ApologizeService { // ... }

The onConstructor parameter menerima pelbagai penjelasan (atau anotasi tunggal seperti dalam contoh ini tertentu) yang diletakkan di atas pembina dihasilkan. Idiom garis bawah berganda telah diperkenalkan kerana masalah keserasian ke belakang. Menurut dokumentasi:

Sebab sintaks pelik adalah menjadikan ciri ini berfungsi dalam penyusun javac 7; yang @__jenis adalah rujukan anotasi jenis anotasi __(garis bawah double) yang sebenarnya tidak wujud; ini menjadikan kelewatan javac 7 membatalkan proses penyusunan kerana ralat kerana kemungkinan pemproses anotasi kemudian akan membuat __jenisnya.

5. Ringkasan

Dalam tutorial ini, kami menunjukkan bahawa tidak perlu memilih DI berasaskan lapangan berbanding DI berasaskan konstruktor dalam hal peningkatan kod plat boiler.

Terima kasih kepada Lombok, memungkinkan untuk mengautomasikan penjanaan kod biasa tanpa kesan prestasi pada waktu berjalan, menyingkat kod lama yang tidak jelas dengan penggunaan anotasi satu baris.

Kod yang digunakan semasa tutorial tersedia di GitHub.