The official example of the scene description: A pump-type coffee machine (coffeemaker) consists of two main components, pump (Pump) and heater (heater), coffee machine has a function is brewed coffee (brew), when the brewing coffee, will be as follows several steps to open the heater heating , pump pressure, extract the coffee, and then turn off the heater, a cup of coffee even after the production.
In the 5 steps of the previous article, let's break down this example:
Step 1 determine dependencies and dependent objects
Dependent objects are coffeemaker objects, and dependent objects are heater type objects and pump type objects.
Src/coffee/coffeemaker.java
Class Coffeemaker {private final heater heater; private final Pump Pump; 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 (); }}
Src/coffee/heater.java
Interface Heater {void on (); void off (); Boolean ishot ();}
Src/coffee/pump.java
Interface Pump {void Pump ();}
Unlike the previous example, both heater and pump are interfaces. Since it is an interface, it means that you must have a corresponding implementation class in order to create the corresponding object. The implementation class for the Electricheater and heater interfaces, Thermosiphon is the implementation class for the pump interface:
Src/coffee/electricheater.java
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; }}
Src/coffee/thermosiphon.java
Class Thermosiphon implements Pump {private final heater heater; Thermosiphon (heater heater) { this.heater = heater; } @Overridepublic void Pump () { if (Heater.ishot ()) { System.out.println ("= = + Pumping = ="); c18/>}}}
Step 2: Create a @module class
The naming convention for @Module classes is to use the module as the end of the class name. The naming convention for @provides method names in the @module class is prefixed with provide.
Official case there are 2 @module classes used here, and one @module class as part of another @module class.
Src/coffee/dripcoffeemodule.java
@Module (includes = Pumpmodule.class) class Dripcoffeemodule {@Provides @Singleton heater provideheater () { return New Electricheater (); }}
@Module Annotations Use an attribute include, which takes pumpmodule as part of itself.
Src/coffee/pumpmodule.java
@Moduleclass pumpmodule {@Provides Pump providepump (Thermosiphon Pump) { return Pump; }}
Step 3. After the @module class has been obtained, the appropriate annotations are made to the places in the Step1 that need to be injected.
Class Coffeemaker {private final lazyThere is still a way to add @inject annotations to the constructor, and by the time the coffeemaker object is created, Dagger2 will automatically call the constructor with @inject. The heater type object and the pump type object that need to be passed into the constructor are also obtained according to @module. In addition, there is a "lazy load" mechanism for the heater property, which means that the true instantiation of the heater type object is made when the Heater.get () method is called the first time (because the heater is the lazy@Module class, when the Provideheater method provides a heater type object, it is directly displayed by invoking the constructor of the Electricheater object, so there is nothing injected into it, That is, Electricheater does not have to do any rewriting. The Providepump method, when providing the pump type object, returns the formal parameter of the method as the return value, in order to ensure that the Dagger2 can automatically assemble the pump attribute when creating the Coffeemaker object. Therefore, you must add @inject annotations for the constructors of the Thermosiphon class, no classes with @inject annotations, Dagger2 are not known, and you cannot automatically create instances of constructor calls.
Src/coffee/thermosiphon.java
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 = ="); } }}
Step 4. Create an interface to connect @inject and @moduleAfter Step2 and STEP3 modify the class created in Step1, the coffeemaker dependency has been described, and the next step is to create a @commpoment interface that "drives" through a parameterless method in the interface. Dagger2 to create a Coffeemaker object, and as this object is built, all dependent objects in the coffeemaker are assembled. In the official example, this interface is provided as an internal interface:
Src/coffee/coffeeapp$coffee.java
@Singleton @Component (modules = {Dripcoffeemodule.class}) public interface Coffee { coffeemaker maker (); }
Step 5. Create an instance of the coffee type using the Dagger2 auto-generated @commpoment interface implementation class. Once an instance of the coffee type is created using the Dagger2 automatically generated @commpoment interface implementation class, you can call the Maker method to get an instance of the coffeemaker type. All dependencies in this coffeemaker instance are now assembled. In the official case, this is the case:
Src/coffee/coffeeapp.java
public class Coffeeapp {@Singleton @Component (modules = {Dripcoffeemodule.class}) publicinterface Coffee { Cof Feemaker maker (); } public static void Main (string[] args) { Coffee Coffee = Daggercoffeeapp_coffee.builder (). build (); Coffee.maker (). Brew (); }}
the @Component interface is rendered as an internal interface to the Coffeeapp. Then the implementation class name that Dagger2 automatically generates for this interface is the Dagger external class name _ interface name, or Daggercoffeeapp_coffee. The corresponding builder method is then called to create the coffee instance. Official example When you create an instance of the Coffee type, you use Daggercoffeeapp_coffee.builder (). Build (), if you write the method exactly as in the previous example, complete the DAGGERCOFFEEAPP_ Coffee.builder (). Dripcoffeemodule (Newdripcoffeemodule ()). build (); the effect is exactly the same, by looking at the Daggercoffeeapp_ Coffee The source code can be learned. Also, if the creation of a @module class instance is created by using the default parameterless constructor, it can be abbreviated to daggercoffeeapp_coffee.create () without the build mode. In addition, if Daggercoffeeapp_coffee has been generated, making changes to @inject or @module does not affect the Daggercoffeeapp_coffee, However, the @commpoment interface or Daggercoffeeapp_coffee call method of the relevant code to make changes, in eclipse will be the Daggercoffeeapp_coffee class error. You are forced to rebuild the project at this time (rebuild). But eclipse is not rebuild this function key. To rebuild a project in eclipse, you can refer to "Building dagger and Dagger2 use environments in Eclipse" by first annotation processing's enable projectspecific Settings option to tick off, click "Apply", at this point, eclipse will have a hint, click Yes to the project once rebuild, the results of rebuild is certainly wrong, and then re-annotation Processing the Enable Projectspecific settings option is checked, click "Apply", at this point eclipse will appear again a prompt, click Yes to the project again rebuild, At this point, you can get the right Daggercoffeeapp_coffee class.
Finally, in Step2, if you do not use the includes attribute for @module annotations, you can combine dripcoffeemodule and pumpmodule into one @module class:
Src/coffee/newdripcoffeemodule.java
@Modulepublic class Newdripcoffeemodule { @[email protected] Heater providheater () { returnnew electricheater ( ); } @[email protected] Pump providepump (heater heater) { returnnew thermosiphon (heater); }}
when returning the Thermosiphon object in the Providepump method, because the constructor requires an object of type heater, the object of this heater type is passed in from the method parameter, When Dagger2 is looking for this heater type object, it will automatically assemble a Electricheater instance in accordance with the Providheater method. This can refer to the source code of the Daggercoffeeapp_coffee class to see how it handles the @provides method in the @module class. Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Dagger2 official Coffeemaker Case Breakdown Description