Memahami Inversion of Control vs Dependency Injection Pada Spring Framework
Sebelum lebih jauh mempelajari dan membangun aplikasi Java mengenai Spring Framework, terlebih dahulu penulis akan mengulas mengenai konsep dasar dari Spring Framework yaitu Inversion of Control, dan Dependency Injection. Kedua istilah tersebut sering dibahas di banyak buku yang membahas tentang Spring namun masih sedikit developer Java yang memahami istilah tersebut dan mengetahui apa perbedaan dari keduanya.
Di banyak tulisan atau artikel yang berbahasa indonesia memang ada beberapa yang membahas mengenai Spring Framework tapi masih jarang (jika tidak ingin dibilang tidak ada) penulis yang mau membahas konsepnya dengan sangat mendasar. Itulah mengapa penulis ingin memulai terlebih dahulu dengan pembahasan ini.
- Inversion of Control
Inversion of Control jika diterjemahkan secara literer berarti “pembalikan kendali”. Maksudnya, secara istilah, adalah membalik (atau memindahkan) kendali (atau tanggung jawab) pengelolaan object yang semula dilakukan oleh program dipindahkan ke Framework atau Container.
Misalkan, Terdapat sebuah class bernama Karyawan
seperti berikut
public class Karyawan { private int id; private String name; private String country; //get set is omitted }
Biasanya, untuk membuat object dari class Karyawan
, digunakan sintaks new seperti berikut
Karyawan karyawan = new Karyawan()
Nah, IoC adalah teknik dalam software engineering yang memindahkan tanggung jawab pembuatan dan pengelolaan object tidak lagi di code melainkan di framework dan Container.
Lalu apa itu Container?
Di dalam terminologi software development istilah Container digunakan untuk menjelaskan komponen yang dapat menampung ( contain ) komponen – komponen lain di dalamnya. Misalnya Apache Tomcat adalah Web / Container yang menampung servlet. Sedangkan JBoss disebut sebagai application server / container, yang juga merupakan EJB Container.
Container bertugas membuat object dan mengkonfigurasi serta menghubungkan ke code yang memerlukan, juga mengelola keseluruhan daur hidup object – object tersebut
- Spring Container
Jika pembaca telah memahami apa itu Container, maka akan menjadi mudah mengerti apa itu Spring Container. Spring Container adalah komponen sentral dari Spring Framework yang berfungsi menampung semua komponen object (kemudian disebut, spring bean) dan menangani daur hidupnya secara keseluruhan.
Untuk mengenali masing – masing beans yang ada di dalam Container, Spring menggunakan konfigurasi metadata yang dapat direpresentasikan dalam format XML atau dalam bentuk anotasi java. Hal ini mirip dengan Apache Tomcat yang merupakan servlet container, juga membaca web.xml
untuk mengidentifikasi servlet mana yang akan dibentuk.
- Dependency Injection
Dependency Injection (DI) adalah design pattern di dalam software engineering modern yang sangat penting untuk memudahkan sebuah program untuk dibuat unit test-nya. kebalikan dari DI adalah hardcoded dependencies.
Dalam banyak referensi juga disebutkan bahwa DI adalah salah satu implementasi dari IoC, atau bagaimana teknis dari konsep IoC diterapkan.
Misalkan terdapat class Perusahaan
yang punya dependensi terhadap kelas Karyawan
, jika digunakan hardcoded dependency maka ditulis sebagai berikut
public class Perusahaan { private Karyawan karyawan = new Karyawan(); }
dengan DI menjadi sebagai berikut
public class Perusahaan { private Karyawan karyawan; public Perusahaan(Karyawan karyawan){ this.karyawan=karyawan; } }
Mengelola DI dengan pendekatan “tradisional” akan membuat keseluruhan program semakin rumit. Dalam contoh ini, diperlukan class lain, untuk membuat object Karyawan
dan menginjeksikannya ke kelas Perusahaan
misalnya PerusahaanService
public class PerusahaanService { private Perusahaan perusahaan; public PerusahaanService() { Karyawan karyawan =new Karyawan(); this.perusahaan = new Perusahaan(karyawan); } }
Code tersebut menyebabkan kerumitan lain, karena kini terdapat dependensi antara PerusahaanService
dan Karyawan
, sebuah hal yang tentu tidak diinginkan. Belum lagi, dependensi antara PerusahaanService
dengan objectPerusahaan
Namun ini bukan berarti design pattern tersebut gagal. DI adalah implementasi bagaimana IoC diterapkan. Yang perlu dilakukan adalah memindahkan tanggungjawab (atau bahasa teknisnya, inversion of Control) injeksi dependensi dari yang semula dilakukan code menjadi dilakukan oleh Framework.
- Depency Injection X Inversion of Control
Dengan menggunakan IoC, Dependency akan dikelola oleh IoC Container sehingga IoC Container – lah yang akan membuat object Karyawan
dan menginjeksikan object tersebut ke Perusahaan
.
Spring IoC Container direpresentasikan oleh interface org.springframework.context.ApplicationContext
yang bertanggungjawab membentuk instance, melakukan konfigurasi hingga merakit beans.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <bean id="karyawan" class="com.subrutin.belajarspring.domains.Karyawan"> <property name="country" value="Indonesia" /> <property name="id" value="1" /> <property name="name" value="Bambang" /> </bean> <bean id="perusahaan" class="com.subrutin.belajarspring.domains.Perusahaan"> <constructor-arg ref="karyawan" /> </bean> </beans>
Jika pembaca baru belajar Spring Framework, konfigurasi tersebut akan nampak tidak familiar, namun setelah beberapa saat anda membaca, konfigurasi tersebut akan mudah dipahami. Pada baris 5-9, spring akan membuat object karyawan
dengan nilai yang diatur pada tag property
Pada baris 10-12, Spring akan menyuntikkan (inject) object Karyawan
ke kelas Perusahaan
melalui argumen pada Constructor.
Pembaca dapat mengunduh source code dari program yang dibahas pada tulisan ini di tautan berikut