Google Guice Dependency Injection Beispiel Tutorial

Google Guice ist das Framework zur Automatisierung der Abhängigkeitsinjektion in Anwendungen. Wenn Sie direkt hier gelandet sind, empfehle ich Ihnen, sich das Beispiel zur Abhängigkeitsinjektion anzusehen, in dem wir die Probleme mit dem traditionellen Ansatz der Objekterstellung erläutert haben und die Implementierungsvorteile der Abhängigkeitsinjektion kennenlernen. Im letzten Tutorial haben wir gelernt, wie wir die Abhängigkeitsinjektion manuell in Anwendungen implementieren können. Aber wenn die Anzahl der Klassen in einer Anwendung wächst, ist es besser, nach einem Framework zu suchen, um diese Aufgabe zu automatisieren. Google Guice ist eines der führenden Frameworks, dessen Hauptaufgabe darin besteht, die automatische Implementierung der Abhängigkeitsinjektion bereitzustellen. Wir werden am selben Beispiel wie im letzten Beitrag arbeiten und lernen, wie wir Google Guice verwenden können, um den Implementierungsprozess für die Abhängigkeitsinjektion zu automatisieren. Die Google Guice-Abhängigkeiten sind im Maven Central verfügbar. Für Maven-Projekte können Sie also die folgende Abhängigkeit hinzufügen.

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

Wenn Sie eine einfache Java-Anwendung haben, können Sie die JAR-Datei von der Google Guice-Homepage auf Google Code herunterladen. Beachten Sie, dass Sie in diesem Fall auch die transitiven Abhängigkeiten im Klassenpfad haben müssen, ansonsten erhalten Sie eine Laufzeit-Ausnahme. Für mein Beispiel habe ich ein Maven-Projekt, dessen Projektstruktur wie im folgenden Bild aussieht. Lassen Sie uns nun jeden der Komponenten einzeln betrachten.

Dienstklassen

package com.journaldev.di.services;

public interface MessageService {

	boolean sendMessage(String msg, String receipient);
}

MessageService-Schnittstelle bietet den grundlegenden Vertrag für die Dienste.

package com.journaldev.di.services;

import javax.inject.Singleton;

//import com.google.inject.Singleton;

@Singleton
public class EmailService implements MessageService {

	public boolean sendMessage(String msg, String receipient) {
		//etwas ausgefeilter Code zum Senden von E-Mails
		System.out.println("Email Message sent to "+receipient+" with message="+msg);
		return true;
	}

}

EmailService ist eine der Implementierungen von MessageService. Beachten Sie, dass die Klasse mit der @Singleton-Annotation versehen ist. Da Serviceobjekte durch Injektor-Klassen erstellt werden, wird diese Annotation bereitgestellt, um sie wissen zu lassen, dass die Dienstklassen Singleton-Objekte sein sollten. Google Guice 3.0 hat die Unterstützung für JSR-330 hinzugefügt, und wir können Annotationen aus dem com.google.inject– oder javax.inject-Paket verwenden. Angenommen, wir haben eine weitere Dienstimplementierung zum Senden von Facebook-Nachrichten.

package com.journaldev.di.services;

import javax.inject.Singleton;

//import com.google.inject.Singleton;

@Singleton
public class FacebookService implements MessageService {

	public boolean sendMessage(String msg, String receipient) {
		//einiger komplexer Code zum Senden von Facebook-Nachrichten
		System.out.println("Message sent to Facebook user "+receipient+" with message="+msg);
		return true;
	}

}

Verbraucherklassen

Da wir die Dependency Injection in unserer Anwendung implementieren, werden wir die Dienstklasse in der Anwendung nicht initialisieren. Google Guice unterstützt sowohl die auf Settern basierende als auch die konstruktorbasierte Dependency Injection. Unsere Anwendungsklasse, die den Dienst verwendet, sieht folgendermaßen aus.

package com.journaldev.di.consumer;

import javax.inject.Inject;

//import com.google.inject.Inject;
import com.journaldev.di.services.MessageService;

public class MyApplication {

	private MessageService service;
	
// Konstruktor-basierte Injektion
//	@Inject
//	public MyApplication(MessageService svc){
//		this.service=svc;
//	}
	
	// Setter-Methoden-Injektion
	@Inject
	public void setService(MessageService svc){
		this.service=svc;
	}
	
	public boolean sendMessage(String msg, String rec){
		// Hier einige Geschäftslogik
		return service.sendMessage(msg, rec);
	}
}

Beachten Sie, dass ich den Code für die konstruktorbasierte Injektion kommentiert habe. Dies ist nützlich, wenn Ihre Anwendung auch andere Funktionen bereitstellt, die kein Service-Klassenobjekt benötigen. Beachten Sie auch die @Injector Annotation, diese wird von Google Guice verwendet, um die Implementierungsklasse des Dienstes einzufügen. Wenn Sie mit Annotationen nicht vertraut sind, schauen Sie sich das Java-Annotationen-Tutorial an.

Bindung der Dienstimplementierung

Offensichtlich wird Google Guice nicht wissen, welchen Dienst es verwenden soll. Wir müssen es konfigurieren, indem wir AbstractModule abstrakte Klasse erweitern und eine Implementierung für die Methode configure() bereitstellen.

package com.journaldev.di.injector;

import com.google.inject.AbstractModule;
import com.journaldev.di.services.EmailService;
import com.journaldev.di.services.FacebookService;
import com.journaldev.di.services.MessageService;

public class AppInjector extends AbstractModule {

	@Override
	protected void configure() {
		// den Dienst an die Implementierungsklasse binden
		//bind(MessageService.class).to(EmailService.class);
		
		// MessageService an die Facebook-Nachrichtenimplementierung binden
		bind(MessageService.class).to(FacebookService.class);
		
	}

}

Wie Sie sehen können, können wir jede Implementierung an die Serviceklasse binden. Zum Beispiel, wenn wir zu EmailService wechseln möchten, müssten wir nur die Bindungen ändern.

Client-Anwendung

Unsere Einrichtung ist bereit, schauen wir uns an, wie wir sie mit einer einfachen Java-Klasse verwenden können.

package com.journaldev.di.test;

import com.google.inject.Guice;
import com.google.inject.Injector;

import com.journaldev.di.consumer.MyApplication;
import com.journaldev.di.injector.AppInjector;

public class ClientApplication {

	public static void main(String[] args) {
		Injector injector = Guice.createInjector(new AppInjector());		
		
		MyApplication app = injector.getInstance(MyApplication.class);
		
		app.sendMessage("Hi Pankaj", "[email protected]");
	}

}

Die Implementierung ist sehr leicht zu verstehen. Wir müssen ein Injector-Objekt mit der Methode createInjector() der Guice-Klasse erstellen, wo wir unser Implementierungsobjekt der Injektor-Klasse übergeben. Dann verwenden wir den Injektor, um unsere Verbrauchsklasse zu initialisieren. Wenn wir die obige Klasse ausführen, wird folgende Ausgabe erzeugt.

Message sent to Facebook user [email protected] with message=Hi Pankaj

Wenn wir die Bindungen in der AppInjector-Klasse zu EmailService ändern, dann wird folgende Ausgabe erzeugt.

Email Message sent to [email protected] with message=Hi Pankaj

JUnit-Testfälle

Da wir die MyApplication-Klasse testen möchten, müssen wir keine tatsächliche Serviceimplementierung erstellen. Wir können eine einfache Mock-Service-Implementierungsklasse wie unten haben.

package com.journaldev.di.services;

public class MockMessageService implements MessageService{

	public boolean sendMessage(String msg, String receipient) {
		return true;
	}

}

Meine JUnit 4 Testklasse sieht wie folgt aus.

package com.journaldev.di.test;


import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.journaldev.di.consumer.MyApplication;
import com.journaldev.di.services.MessageService;
import com.journaldev.di.services.MockMessageService;

public class MyApplicationTest {

	private Injector injector;
	
	@Before
	public void setUp() throws Exception {
		injector = Guice.createInjector(new AbstractModule() {
			
			@Override
			protected void configure() {
				bind(MessageService.class).to(MockMessageService.class);
			}
		});
	}

	@After
	public void tearDown() throws Exception {
		injector = null;
	}

	@Test
	public void test() {
		MyApplication appTest = injector.getInstance(MyApplication.class);
		Assert.assertEquals(true, appTest.sendMessage("Hi Pankaj", "[email protected]"));;
	}

}

Beachten Sie, dass ich die Klasse MockMessageService an die Klasse MessageService binde, indem ich eine anonyme Implementierung der Klasse AbstractModule in der Methode setUp() habe, die vor den Testmethoden ausgeführt wird.

Google Guice-Projekt herunterladen

Das ist alles für das Google Guice-Beispiel-Tutorial. Die Verwendung von Google Guice zur Implementierung der Dependency Injection in der Anwendung ist sehr einfach und funktioniert wunderbar. Es wird in Google-APIs verwendet, sodass wir davon ausgehen können, dass es sich um hoch getesteten und zuverlässigen Code handelt. Laden Sie das Projekt oben herunter und probieren Sie es aus, um mehr zu erfahren.

Source:
https://www.digitalocean.com/community/tutorials/google-guice-dependency-injection-example-tutorial