Injeksi Ketergantungan Konstruktor di Musim Semi

1. Perkenalan

Bisa dibilang salah satu prinsip pengembangan terpenting dari desain perangkat lunak modern adalah Dependency Injection (DI) yang secara alami mengalir keluar dari prinsip penting lainnya: Modularitas.

Artikel ini akan membahas jenis teknik DI tertentu yang disebut Injeksi Ketergantungan Berbasis Konstruktor dalam Pegas - yang secara sederhana, berarti bahwa komponen yang diperlukan diteruskan ke kelas pada saat pembuatan contoh.

Untuk memulai kita perlu mengimpor ketergantungan konteks pegas di pom.xml kita :

 org.springframework spring-context 5.2.8.RELEASE 

Kemudian kita perlu menyiapkan file Konfigurasi . File ini bisa berupa POJO atau jika Anda lebih suka, file XML.

2. Konfigurasi Berbasis Anotasi

File konfigurasi Java terlihat seperti objek Java biasa dengan beberapa penjelasan tambahan:

@Configuration @ComponentScan("com.baeldung.constructordi") public class Config { @Bean public Engine engine() { return new Engine("v8", 5); } @Bean public Transmission transmission() { return new Transmission("sliding"); } } 

Di sini kita menggunakan anotasi untuk memberi tahu runtime Spring bahwa kelas ini adalah penyedia definisi kacang ( anotasi @Bean ) dan bahwa pemindaian konteks untuk kacang tambahan perlu dilakukan dalam paket com.baeldung.spring . Selanjutnya, kami mendefinisikan kelas Mobil :

@Component public class Car { @Autowired public Car(Engine engine, Transmission transmission) { this.engine = engine; this.transmission = transmission; } }

Spring akan menemukan kelas Car kami saat melakukan pemindaian paket dan akan menginisialisasi instance-nya dengan memanggil konstruktor beranotasi @Autowired .

Instance Engine dan Transmisi akan diperoleh dengan memanggil metode beranotasi @Bean dari class Config . Terakhir, kita perlu mem-bootstrap ApplicationContext menggunakan konfigurasi POJO kita:

ApplicationContext context = new AnnotationConfigApplicationContext(Config.class); Car car = context.getBean(Car.class);

3. Injeksi Konstruktor Implisit

Mulai Musim Semi 4.3, kelas dengan konstruktor tunggal dapat menghilangkan anotasi @Autowired . Sedikit kenyamanan dan penghapusan boilerplate!

Selain itu, juga dimulai dengan 4.3, injeksi berbasis konstruktor dapat dimanfaatkan dalam kelas beranotasi @Configuration . Dan ya, jika kelas seperti itu hanya memiliki satu konstruktor, anotasi @Autowired juga dapat dihilangkan.

4. Konfigurasi Berbasis XML

Cara lain untuk mengonfigurasi Spring runtime dengan injeksi dependensi berbasis konstruktor adalah dengan menggunakan file konfigurasi XML:

Perhatikan bahwa konstruktor-arg dapat menerima nilai literal atau referensi ke kacang lain dan bahwa indeks dan tipe eksplisit opsional dapat disediakan. Atribut tipe dan indeks dapat digunakan untuk menyelesaikan ambiguitas (misalnya jika konstruktor mengambil beberapa argumen dari tipe yang sama).

atribut name juga dapat digunakan untuk pencocokan variabel xml ke java, tetapi kemudian kode Anda harus dikompilasi dengan tanda debug aktif.

Konteks aplikasi Spring, dalam hal ini, perlu di-bootstrap menggunakan ClassPathXmlApplicationContext :

ApplicationContext context = new ClassPathXmlApplicationContext("baeldung.xml"); Car car = context.getBean(Car.class);

5. Pro dan Kontra

Injeksi konstruktor memiliki beberapa keunggulan dibandingkan injeksi lapangan.

Manfaat pertama adalah kemampuan untuk diuji. Misalkan kita akan menguji unit kacang Spring yang menggunakan injeksi lapangan:

public class UserService { @Autowired private UserRepository userRepository; }

Selama pembuatan instance UserService , kita tidak dapat menginisialisasi status userRepository . Satu-satunya cara untuk mencapai ini adalah melalui API Refleksi, yang benar-benar merusak enkapsulasi. Selain itu, kode yang dihasilkan akan kurang aman dibandingkan dengan panggilan konstruktor sederhana.

Selain itu, dengan injeksi lapangan, kami tidak dapat menerapkan invarian tingkat kelas.Jadi dimungkinkan untuk memiliki instance UserService tanpa userRepository yang diinisialisasi dengan benar . Oleh karena itu, kami mungkin mengalami NullPointerException acak di sana-sini. Selain itu, dengan injeksi konstruktor, lebih mudah untuk membuat komponen yang tidak dapat diubah.

Selain itu, menggunakan konstruktor untuk membuat instance objek lebih alami dari sudut pandang OOP.

Di sisi lain, kelemahan utama injeksi konstruktor adalah verbositasnya terutama ketika kacang memiliki beberapa dependensi. Terkadang itu bisa menjadi berkah terselubung, karena kita mungkin berusaha lebih keras untuk meminimalkan jumlah ketergantungan.

6. Kesimpulan

Tutorial singkat ini telah memamerkan dasar-dasar dari dua cara berbeda untuk menggunakan Injeksi Ketergantungan Berbasis Konstruktor menggunakan kerangka kerja Spring.

The implementasi penuh dari tutorial ini dapat ditemukan lebih pada GitHub.