当你在创建一个类实例的时候需要其他的支持类实例的支持时,你可以选择new一个实例传入,当然你也可以选择依赖注入来简化你的代码。举个最简单的例子:
public class Cooker{
private CookTool tool;
public Cooker(CookTool tool){
this.tool= tool;
}
}
显然,当你想创建一个Cooker类时,你需要CookTool类实例的支持,于是你会用new Cooker(new CookTool());这样的方式来创建Cooker类实例。但是如果这样的类似的情况以及创建的类实例的数量相当多的时候就会让你感到头疼了,因为这就是写重复的代码。而dagger2就是你的救星,它可以在你的合理配置下,帮你自动生动这些代码。
经过一段时间的了解,个人认为dagger2最主要的三个成分是@Inject注解、Component、Module。@Inject注解用于标记你需要依赖注入的类实例以及该类实例对应的构造方法,如上述的father。Module的主要功能在于当你需要第三方库里面的类实例时,由于你无法在源码里面添加@Inject注解,所以你可以在Module里面先获取第三方库的类实例,然后再提供出去(需要@Provides注解),当然非第三方库类你也可以再Module里面创建然后再提供出去。而对于Component,我们可以形象地将它称为注射器,它负责把@Inject和Module提供的类实例注射到你想到的地方。还是上述的例子,假设我们要把Cooker注入到一个Activity:
第一步:
public class Cooker{
@Inject //标记要注入的地方
CookTool tool;(依赖注入的类不支持private)
@Inject //我们需要在Activity里注入Cooker实例
public Cooker(CookTool tool){
this.tool = tool;
}
//测试方法
public String makeFood(String msg){
Log.e("cook","I use "+msg);
}
}
public class CookTool{
@Inject //标记对应的类构造器
public CookTool(){
}
}
上述是dagger2依赖注入的第一种代码实现,也就是用@Inject注解,第二种是用Module:
@Module //新建一个Module类,记住要用@Module注解
public class BaseActivityModule{
//Module的构造器
public BaseActivityModule(){
}
@Provides //提供注解
Cooker getCooker(){ //方法名随意,类型必须正确
return new Cooker(new CookTool());
}
}
第二步,创建Component:
@Sington @Component //返回单例,记得用@Component注解
(modules= {BaseActivityModule.class}) //将需要的Module包含进来
public class BaseActivityComponent{
void inject(BaseActivity baseActivity) //注射到BaseActivity
}
第三步,依赖注入:
public BaseActivity extends AppCompatActivity{
BaseActivityComponent component;
@Inject
Cooker cooker;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState){
//DaggerBaseActivityComponent是自动生成的,rebuild project之后可以查看,dagger2用的是builder模式
component = DaggerBaseActivityComponent.builder().
BaseActivityModule(new BaseActivityModule()).build();
component.inject(this); //依赖注入,对应上面的BaseActivityComponent
cooker.makeFood("knife");
}
}
上述三步缺一不可,运行之后查看日志就能知道咱们的依赖注入的目的是否达成了。这里需要注意的是,dagger2在寻找依赖提供的时候会优先选择Module提供的依赖,然后再是@Inject提供的依赖,还有一点是上述给出的例子其实是一个递归依赖注入(将CookTool注入Cooker,再将注入好的Cooker注入Activity),希望大家注意掌握与运用。