Dagger2学习笔记1(基础概念学习)
Dagger2学习笔记2(学习Dagger2的简单使用)
上篇中学习了如何使用 Dagger2, 很多小伙伴可能一脸懵, 现在我们将学习 dagger2中各个注解的含义以及使用的注意事项.
Dagger2中的注解
4个基础注解,经常使用
- @Inject
- @Module
- @Provides
- @Component
- @Named
- @Qualifier
- @Singleton
- @Scope
...
@inject
作用:
1 依赖注入类中的依赖变量声明,让 dagger2为其提供依赖
2 被依赖的类的构造方法上申明, 通过标记构造函数让 Dagger2 来使用, 可以在需要这个类实例的时候来找到这个构造函数并把相关实例new出来
eg.
@Inject
BuyCarSuccessPresenterImpl mPresenter;
@Inject
public Dogs(Dog dog){
this.dog = dog;
}
@Module
作用:
1 修饰类, 与@Inject作用相同,用来提供依赖,区别在于Module为那些没有构造方法的类如工具类等提供依赖比如,系统工具类, 第三方 Jar 包等, 能用 @Inject 提供工具类的
@Provides
作用:
用于注解被@ Module 修饰的类中的方法, 当需要该类的依赖时会去找返回值为该类的方法
@Module
public class MainModule {
@Provides
Dog provideDog(){
Dog dog = new Dog();
dog.setColor("yellow");
return dog;
}
@Component
作用:
1 注解一个接口或者抽象类,
2 为inject和module之间建立联系,可以理解为不赚差价的中间商
eg. 在编译时会产生对应的类的实例, 为依赖方和被依赖方提供桥梁,把相关的依赖注入到其中.
@Component(modules = MainModule.class)
public interface MainComponent{
void inject(MainActivity activity);}
抽象方法inject参数为注入的activity类, build之后会生成一个以dagger开头mainComponent结尾的类。
public class MainActivity extends AppCompatActivity {
@Inject
Dogs dogs;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainComponent
.builder()
.mainModule(new MainModule())
.build()
.inject(this);
}
}
在activity中调用生成dagger的inject方法, 完成依赖注入
以上为四个常用的基本注解类, 除此之外还有很多非基本的注解
@Named
作用: 用于区分我们获取依赖的方法
Dagger2寻找依赖是根据我们提供方法的返回值进行匹配的, 当我们遇到不同提供依赖的方法但是返回值类型是相同的应该怎么办呢? Dagger2提供了 Named 注解,用于区分相同返回值类型的不同方法.
定义提供依赖的方法:
@Module
public class MainModule {
@Named("yellow")
@Provides
Dog provideYellowDog(){
Dog dog = new Dog();
dog.setColor("yellow");
return dog;
}
@Named("black")
@Provides
Dog provideBlackDog(){
Dog dog = new Dog();
dog.setColor("black");
return dog;
}
两个提供依赖的方法返回值都是 Dog, 但是用 Named加以区分
使用:
public class SecondActivity extends BaseAcitivity {
@Inject
@Named("black")
Dog dog;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
((TextView)findViewById(R.id.tv)).setText(dog.toString());
...
}
此时拿到的对象是 BlackDog
@Qulifier
作用: 与 Named一致, Named是继承Qulifier的, 相当于 Dagger2为我们提供的标准化的区分器, 我们也可以进行自定义:
public class MainModule {
@Provides
@YellowDog
Dog provideYellowDog(){
Dog dog = new Dog();
dog.setColor("yellow");
return dog;
}
....
}
public class MainActivity extends BaseAcitivity {
@Inject
@YellowDog
Dog dog;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
((TextView)findViewById(R.id.tv)).setText(dog.toString());
...
}
输出结果为 YellowDog, 与 @Named("yellow")效果一致
@Singleton
作用: 声明单例模式, Dagger2的机制是需要某个对象是回去找对应提供的实例化方法, 多次寻找就会创建多个对象, 当我们需要让对象保持单例模式时, 要使用@Singleton修饰提供依赖的方法
使用: 修饰Module 中需要使用单例的方法上, 保证实例全局都是单例
@Module
public class MainModule {
@Singleton
@Provides
Dog provideDog(){
Dog dog = new Dog();
dog.setColor("yellow");
return dog;
}
....
}
注意: 1.module 中有方法使用Singleton修饰时, 引用 module 的 component 也要使用@Singleton修饰, 否则编译会报错. 2.想要使用 Singleton 保持全局单例,需要配合Component 使用@Depencies注解以及配合Applicaition 的全局单例性质才可以实现, 后文中会进行详细介绍.
@Singleton
@Component(modules = MainModule.class)
public interface MainComponent {
}
通过构造方法提供依赖要保证单例时, 我们需要在该类的类名上使用@ Singleton 修饰, 切记不是构造方法上!
@Scope
查看源码可以发现@Singleton是使用注解@Scope 修饰的, 而@Scope是用来声明作用域的, Dagger2的机制:在同一作用域下,provides 提供的依赖对象会保持单例, 脱离这一作用域, 单例作用就会失效, 可以说 @Singleton 是@Scope 注解的一个标准, 我们还可以去自定义一些 Scope 注解.
@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}
Scope注解需要我们进行自定义, 自定义方法和 Singleton作用一致, 当我们使用 @Dependies 进行 Component间的依赖的时候, 如果有提供单例的依赖, 根据 dagger2的机制, 这时我们依赖的Component不能使用同一 scope 进行修饰, 否则会报错, 所以就用到了自定义的scope, 从而区分 Component 之间的层级关系.
下一篇中我们将学习Singleton如何实现全局单例.
Dagger2学习笔记4(@Singleton 与@ Scope 实现全局单例与作用域单例)
Dagger2学习笔记5(关于Lazy,Provide的使用)
End~
特别谢明:Dagger2 入门,以初学者角度