1. Pengenalan
  2. Dependency injection framework
  3. Google Guice
  4. Dagger
  5. Spring

Dalam tutorial database, saya ada sentuh sedikit mengenai inversion of control. Maksud inversion of control memang susah sikit nak terangkan tanpa contoh.

Jadi sebelum mula tutorial ini, sila lihat code di sini terlebih dahulu.

Pengenalan

Dalam code tersebut, kita ada dua servis (atau module), servis untuk User dan servis untuk Greeting. Dalam implementation, servis Greeting memerlukan servis User. Jadi kita memerlukan satu cara untuk memberi class servis User kepada servis Greeting.

Untuk code ini, saya memberi class servis User kepada servis Greeting dalam file Main.java. Inilah yang dipanggil inversion of control. Maksudnya cara saya memberi dependency bukannya terletak dalam constructor servis Greeting, tetapi di tempat lain.

Cara saya memberi dependency seperti ini dipanggil dependency injection.

Dependency injection framework

Kalau anda lihat kembali code untuk membuat dependency injection, barangkali anda terfikir bagaimana jika sesuatu servis perlukan terlalu banyak servis lain. Code tersebut nanti mungkin akan menjadi terlampau panjang dan serabut.

Ya, dalam situasi sebenar memang akan ada servis yang bergantung kepada banyak servis lain. Untuk menyelesaikan masalah ini, kita boleh menggunakan dependency injection framework.

Antara dependency injection framework ialah Guice, Dagger, dan Spring. Untuk tutorial ini, kita akan menggunakan Guice sebagai contoh.

Google Guice

Google Guice hanyalah sebuah library, jadi kita tambah sahaja library tersebut. Jika menggunakan Maven, tambah ini ke file pom.xml:

<dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>4.1.0</version>
</dependency>

Dengan menggunakan Guice, kita boleh membahagikan setiap servis sebagai module. Untuk membuat module menggunakan Guice, buat satu class dan extends class tersebut dengan AbstractModule. Contoh untuk UserModule:

public class UserModule extends AbstractModule {
    @Override
    protected void configure() {

    }
}

Dalam method configure(), kita boleh letak bagaimana rupa dependency untuk module tersebut. Contoh:

public class UserModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(UserService.class).to(UserServiceImpl.class);
        bind(UserLocaleRepository.class).to(UserLocaleRepositoryImpl.class);
    }
}

Di sini bermaksud, apabila program jumpa interface UserService, program itu perlu memberi class UserServiceImpl. Apabile jumpa interface UserLocaleRepository, program itu perlu memberi UserLocaleRepositoryImpl.

Setelah selesai dengan module, pergi ke class yang memerlukan dependency iaitu UserServiceImpl. Kemudian tambah annotation @Inject di atas constructor. Contoh:

@Inject
public UserServiceImpl(final UserLocaleRepository userLocaleRepository) {
    this.userLocaleRepository = userLocaleRepository;
}

Apabila ditambah @Inject, class tersebut akan memberitahu Guice bahawa dia perlukan Guice untuk inject dependency yang ada di parameter constructor tersebut. Kemudian Guice pun akan cari dependency yang diperlukan daripada module.

Setelah selesai dengan UserModule, buat benda yang sama dengan GreetingModule.

Setelah selesai, kita boleh tukar code di Main.java.

Untuk menggunakan servis dengan Guice, kita boleh menggunakan method createInjector() kemudian sertakan module-module yang kita perlukan. Sebagai contoh:

final Injector injector = Guice.createInjector(new UserModule(), new GreetingModule());

Untuk mendapatkan servis, gunakan method getInstance() daripada injector seperti berikut:

final GreetingService greetingService = injector.getInstance(GreetingService.class);

Anda boleh lihat code yang pernuh di sini.

Sebagai latihan, anda boleh refactor (menukar) code untuk tutorial database menggunakan dependency injection framework. Satu benda yang saya tidak sentuh di sini ialah provider. Anda boleh menggunakan provider untuk database connection. Rujuk documentation cara untuk menggunakan provider.

Dagger

Jika anda ingin menggunakan dependency injection framework untuk aplikasi Android, anda boleh menggunakan Dagger.

Spring

Bagi yang rajin mengambil tahu tentang Java pasti ada terdengar atau terbaca mengenai Spring. Spring pada mulanya hanyalah dependency injection framework tetapi makin lama makin berkembang ke web application framework.

Jika anda menggunakan Spring Boot, anda tidak perlu pun menulis module atau injector seperti Guice. Semuanya hanya menggunakan annotation.