用Dagger理解Java中的依赖注入
我熟悉传统设计模式中的依赖倒置原则,在传统设计模式中,您有一个抽象产品,它在请求工厂方法的类中执行任务。但依赖注入的不同之处在于它使用注释来生成产品 我正在回顾这个例子。这就是最终结果:用Dagger理解Java中的依赖注入,java,dependency-injection,dagger-2,Java,Dependency Injection,Dagger 2,我熟悉传统设计模式中的依赖倒置原则,在传统设计模式中,您有一个抽象产品,它在请求工厂方法的类中执行任务。但依赖注入的不同之处在于它使用注释来生成产品 我正在回顾这个例子。这就是最终结果: // CoffeeApp.java public class CoffeeApp { @Singleton @Component(modules = { DripCoffeeModule.class }) public interface Coffee { CoffeeMaker maker
// CoffeeApp.java
public class CoffeeApp {
@Singleton
@Component(modules = { DripCoffeeModule.class })
public interface Coffee {
CoffeeMaker maker();
}
public static void main(String[] args) {
Coffee coffee = DaggerCoffeeApp_Coffee.builder().build();
coffee.maker().brew();
}
}
$ java -cp ... coffee.CoffeeApp
~ ~ ~ heating ~ ~ ~
=> => pumping => =>
[_]P coffee! [_]P
我很难理解这句话:
CoffeeMaker maker();
在CoffeeMaker类中,没有make方法。那么这是如何工作的呢
这是我的理解:
CoffeeMaker类在其构造函数中使用@Inject注释:
@Inject CoffeeMaker(Lazy<Heater> heater, Pump pump) {
this.heater = heater;
this.pump = pump;
}
这是否意味着当调用@Inject CoffeeMaker构造函数时,它会依次发现pump引用并搜索PumpModule@Module,然后发现providePump并实例化一个新的热虹吸泵类型?@Donato,你是对的,CoffeeMaker没有maker方法,咖啡界面确实有maker方法。该方法生成器返回CoffeMaker类型的对象。因此,在您的示例中,daggerOffeeApp_Coffee.builder.build;将返回Coffee的一个实现,该实现反过来实现maker方法
问:但请求是什么意思
我的回答:请求意味着注入,即无论你在哪里看到@Inject。例如,下面的私有变量声明请求CoffeeMaker的一个实例
咖啡机依次请求一个实例或加热器和一个泵实例:
因此,在实例化或注入maker时,将实例化并注入加热器实例和泵实例
问题:这是否意味着当调用@Inject CoffeeMaker构造函数时,它会依次发现pump引用并搜索PumpModule@Module,然后发现providePump并实例化热虹吸类型的新泵
我的回答是:没错 Dagger是一种编译时依赖项注入解决方案
界面CoffeeApp.Coffee上的CoffeeMaker行(按原样注释)表示Dagger将生成并编译CoffeeApp.Coffee的实现,该实现具有maker方法的实现,该方法将为您提供一个完全注入的CoffeeMaker实例。如果您愿意,您可以查看Dagger生成的文件DaggerOffeeApp_Coffee.java,它看起来很像上面的实现。幻灯片35和36显示了相应的工厂/提供商实现
这将迫使Dagger在咖啡机实例化时实例化一个新加热器和一个新泵,对吗
是的,通常。尽管您有权在@Provides方法中返回现有实例,或者使用@Singleton之类的注释让Dagger管理现有实例,但Dagger的默认行为是为每个依赖项创建一个新实例,并为该依赖项的每个依赖项创建一个新实例,依此类推
这是否意味着当调用@Inject CoffeeMaker构造函数时,它会依次发现pump引用并搜索PumpModule@Module,然后发现providePump并实例化热虹吸类型的新泵
您几乎是正确的:为了实现该实现,Dagger将检查@Inject CoffeeMaker构造函数,发现咖啡机需要加热器和泵,等等。对于像Guice这样的框架,这一切都发生在运行时,但对于Dagger,所有的分析和映射都发生在编译时。在您的示例中,@Provides Pump方法存在于DripOffeeModule中,Dagger不会搜索该方法:该示例通过CoffeeApp.Coffee上的@Component注释提供该方法。请参阅组件中maker方法的解释
The method’s return type defines which dependency it satisfies.
public MyClass {
@Inject private CoffeeMaker maker;
...
}
@Inject CoffeeMaker(Lazy<Heater> heater, Pump pump) {
this.heater = heater;
this.pump = pump;
}