Über Dagger2, eine DI-Bibliothek für Java / Android, das offizielle Beispiel Kaffee-App Ich möchte den Mechanismus basierend auf (/ master / examples / simple / src / main / java / Coffee) erklären. Die Kaffee-App war jedoch etwas schwer zu verstehen ("@ Binds", "Lazy" usw.), sodass der unten beschriebene Code leicht geändert wurde. Dagger2 User Guide kann mit Wissen von oben bis Mitte verstanden werden (Singletons und Scoped Bindings).
In diesem Beispiel wird versucht, eine Instanz der CoffeeMaker-Klasse mit Dagger2 zu erstellen.
Die CoffeeMaker-Klasse weist die folgenden Abhängigkeiten auf.
https://docs.google.com/presentation/d/1fby5VeGU9CN8zjw4lAb2QPPsKRxx6mSwCe9q7ECNSJQ/pub?start=false&loop=false&delayms=3000&slide=id.p
Das Auflösen dieser Abhängigkeit und das Abrufen einer CoffeeMaker-Instanz kann etwas schwierig sein.
Heater heater = new ElectricHeater();
Pump pump = new Thermosiphon(heater);
CoffeeMaker coffeeMaker = new CoffeeMaker(heater, pump).maker();
coffeeMaker.brew();
Mit Dagger2 sieht der obige Code folgendermaßen aus:
CoffeeMaker coffeeMaker = DaggerCoffeeShop.create().maker();
coffeeMaker.brew();
Auf diese Weise wird der CoffeeMaker-Clientcode von der Komplexität beim Erstellen von Abhängigkeiten befreit. Im Folgenden wird beschrieben, wie Dagger2 diese Abhängigkeiten erstellt.
Dagger verwendet einen Konstruktor mit der Annotation "@ Inject", um eine Instanz zu erstellen.
class Thermosiphon implements Pump {
private final Heater heater;
@Inject
Thermosiphon(Heater heater) {
this.heater = heater;
}
@Override
public void pump() {
if (heater.isHot()) {
System.out.println("=> => pumping => =>");
}
}
}
Wenn eine Thermosiphon-Instanz angefordert wird, wird mit dem obigen Konstruktor eine Thermosiphon-Instanz erstellt.
Hier hängt die Thermosiphon-Klasse von der Heizklasse ab. Dolch identifiziert die im Konstruktor definierten Abhängigkeiten und löst sie auf.
Dagger versucht, die Abhängigkeit zu erfüllen, indem er eine Instanz des angeforderten Typs erstellt, aber die Abhängigkeitserklärung von @ Inject
funktioniert nicht immer.
In den folgenden Fällen funktioniert "@ Inject" nicht.
--Type ist eine Schnittstelle Klassen der 3. Partei können nicht kommentiert werden
In der Kaffee-App werden die Typen, von denen CoffeeMaker abhängt (Heizung und Pumpe), als Schnittstellen deklariert, was oben der Fall ist. In diesen Fällen erstellt die mit "@ Provides" kommentierte Methode eine Instanz.
Beispielsweise deklariert Heater eine Abhängigkeit wie folgt: Definieren Sie eine mit "@ Provides" versehene Methode und geben Sie "Heater" als Rückgabetyp an.
@Provides
static Heater provideHeater() {
return new ElectricHeater();
}
In ähnlicher Weise erklärt Thermosiphon: Die Methode "@ Provides" kann eigene Abhängigkeiten haben.
@Provides
static Pump providePump(Thermosiphon pump) {
return pump;
}
Die Methode "@ Provides" muss zum Modul gehören. Ein Modul ist eine Klasse mit der Annotation "@ Module".
@Module
class DripCoffeeModule {
@Provides
static Heater provideHeater() {
return new ElectricHeater();
}
@Provides
static Pump providePump(Thermosiphon pump) {
return pump;
}
}
Konventionell scheint die Methode "@ Provides" ein Bereitstellungspräfix zu haben, und das Modul hat ein Modulsuffix.
Klassen und Methoden, die durch "@ Inject" und "@ Provides" definiert sind, bilden einen Abhängigkeitsgraphen eines Objekts.
Definieren Sie eine Komponente, um dieses Diagramm zu erstellen.
Eine Komponente ist eine mit @ Component
annotierte Schnittstelle und verfügt über Methoden ohne Argumente.
Der Rückgabetyp dieser Methoden ist der Typ, den Sie auflösen möchten.
Im Folgenden wird eine CoffeeShop-Komponente mit einer Methode definiert, die eine CoffeeMaker-Instanz zurückgibt. Übergeben Sie das Modul an die Komponente, um die Abhängigkeiten darunter zu erstellen. Hier passieren wir das DripCoffeeModule.
@Component(modules = DripCoffeeModule.class)
interface CoffeeShop {
CoffeeMaker maker();
}
Dagger generiert basierend auf dieser Definition automatisch eine Implementierung von CoffeeShop. Der von Dagger generierten Implementierungsklasse wird Dagger vorangestellt. Hier wird eine Implementierungsklasse namens DaggerCoffeeShop generiert.
Die Komponentenimplementierungsklasse verfügt über eine Builder-Methode, mit der Abhängigkeiten erstellt werden.
CoffeeShop coffeeShop = DaggerCoffeeShop.builder()
.dripCoffeeModule(new DripCoffeeModule())
.build();
Im obigen Beispiel wird eine DripCoffeeModule-Instanz manuell erstellt und an den Builder übergeben. Wenn jedoch die folgenden Bedingungen erfüllt sind, ist dieser Vorgang nicht erforderlich.
Wenn für Komponenten alle folgenden Module auf die oben genannten zutreffen, verfügt die Implementierungsklasse über eine Erstellungsmethode, mit der Sie eine Instanz direkt erstellen können, ohne den Builder durchlaufen zu müssen.
CoffeeShop coffeeShop = DaggerCoffeeShop.create();
Schließlich sieht der CoffeeMaker-Clientcode folgendermaßen aus:
CoffeeMaker coffeeMaker = DaggerCoffeeShop.create().maker();
coffeeMaker.brew();
Hier ist der Code mit einer geringfügigen Änderung der offiziellen Kaffee-App. Es wird nur mit den Funktionen in dem oben erläuterten Bereich implementiert.
** * Nur die Annotation "@ Singleton" wird später beschrieben. ** **.
Heater.java(Bleib offiziell)
interface Heater {
void on();
void off();
boolean isHot();
}
Pump.java(Bleib offiziell)
interface Pump {
void pump();
}
ElectricHeater(Bleib offiziell)
class ElectricHeater implements Heater {
boolean heating;
@Override
public void on() {
System.out.println("~ ~ ~ heating ~ ~ ~");
this.heating = true;
}
@Override
public void off() {
this.heating = false;
}
@Override
public boolean isHot() {
return heating;
}
}
Thermosiphon(Bleib offiziell)
class Thermosiphon implements Pump {
private final Heater heater;
@Inject
Thermosiphon(Heater heater) {
this.heater = heater;
}
@Override
public void pump() {
if (heater.isHot()) {
System.out.println("=> => pumping => =>");
}
}
}
DripCoffeeModule.java
@Module
class DripCoffeeModule {
@Singleton
@Provides
static Heater provideHeater() {
return new ElectricHeater();
}
@Provides
static Pump providePump(Thermosiphon pump) {
return pump;
}
}
CoffeeMaker(Bleib offiziell)
class CoffeeMaker {
private final Heater heater;
private final Pump pump;
@Inject
CoffeeMaker(Heater heater, Pump pump) {
this.heater = heater;
this.pump = pump;
}
public void brew() {
heater.on();
pump.pump();
System.out.println(" [_]P coffee![_]P ");
heater.off();
}
}
CoffeeShop.java
@Singleton
@Component(modules = DripCoffeeModule.class)
public interface CoffeeShop {
CoffeeMaker maker();
}
CoffeeApp.java
public class CoffeeApp {
public static void main(String[] args) {
CoffeeMaker coffeeMaker = DaggerCoffeeShop.create().maker();
coffeeMaker.brew();
}
}
@ Singleton
AnnotationBeim Auflösen von Abhängigkeiten versucht Dagger jedes Mal, wenn dies standardmäßig angefordert wird, eine Instanz des Typs zu erstellen. Bei der Kaffee-App funktioniert das Standardverhalten jedoch nicht wie beabsichtigt.
Die Brühmethode von CoffeeMaker besteht darin, die Heizung einzuschalten (heater.on ()), Wasser zu gießen (pump.pump ()), Kaffee zu brühen (println ()) und die Heizung wieder auszuschalten. Gießen Sie Wasser nur, wenn die Heizung eingeschaltet ist. Das Überprüfen, ob die Heizung eingeschaltet ist, wird an die von der Pump-Instanz gehaltene Heat-Instanz delegiert. Zu diesem Zeitpunkt sind es jedoch die von der CoffeeMaker-Instanz gehaltene Heat-Instanz und die von der Pump-Instanz gehaltene Heat-Instanz Sie müssen sich auf dasselbe beziehen.
Wie oben erwähnt, wird Dolch jedes Mal erstellt, wenn ein Typ angefordert wird, sodass er sich nicht wie beabsichtigt verhält. Sie können dann die Annotation "@ Singleton" verwenden, um anzugeben, dass immer dieselbe Instanz zurückgegeben werden soll, wenn der Typ angefordert wird.
Im obigen Code ist die requireHeater-Methode von DripCoffeeModule mit "@ Singleton" versehen, um anzugeben, dass die Heater-Instanz Singleton ist. Die CoffeeShop-Oberfläche ist auch mit "@ Singleton" versehen, sodass die Komponente und ihre untergeordneten Instanzen denselben Lebenszyklus haben.
Ich erklärte den grundlegenden Teil, der der erste Schritt ist, um Dolch zu verstehen. Da dies nur der erste Teil des Benutzerhandbuchs ist, denke ich, dass es noch viel Wissen gibt, das nicht ausreicht, um Dagger zu üben, sondern diejenigen, die Dagger von nun an verwenden möchten, und einige Tage später mein eigenes. Ich dachte, es wäre hilfreich für dich.
Recommended Posts