Dagger2 @Inject @Provide @Module
本文适合于Dagger2 零基础学习。本次阅读需要五分钟。
Dagger2 主要提供了6种注解,这里我主要讲其中的四种
@Inject @Provide @Module @Component
Dagger2是通过依赖注入完成类的初始化。
**这个过程需要三部分:
依赖提供方,依赖注入容器,依赖需求方
**
-
@Inject Inject主要有两个作用
1.作为依赖注提供方使用:在构造函数上,通过标记构造函数让Dagger2来使用(Dagger2通过Inject标记可以在需要这个类实例的时候来找到这个构造函数并把相关实例new出来)从而提供依赖
2.作为依赖需求方:标记在需要依赖的变量Dagger2会帮助初始化,被我们使用。 -
@Provide 用Provide来标注一个方法,该方法可以在需要提供依赖时被调用,从而把预先提供好的对象当做依赖给标注了@Inject的变量赋值。provide主要用于标注Module里的方法
-
@Module 用Module标注的类是专门用来提供依赖的。注意Module类是提供依赖的一个集合,通常它自身是需要被依赖的。而真正被依赖的都是通过@Provide标注的方法提供,所以@Module和@Provide是联合使用的。
-
@Component Component一般用来标注接口,被标注了Component的接口在编译时会产生相应的类的实例来作为提供依赖方和需要依赖方之间的桥梁,把相关依赖注入到其中。
图片来自于[Maydaaa](https://dreamerhome.github.io/2016/07/11/dagger%20for%20code/)
**对上述内容请记住依赖注入过程需要三部分:
依赖提供方,依赖注入容器,依赖需求方
**
对上述描述不清楚的,请先看下面的案例,再去理解上面的内容。
案例
常规做法
我们要在TestUser 中创建一个User
public class User {
String userName;
int age;
}
如果我们想使用User 我们需要new出来然后使用
public class TestUser {
User user;
public static void main(String[] arg) {
TestUser testUser = new TestUser();
testUser.user = new User();
testUser.user.userName = "name";
}
}
在上述例子中我们如果希望使用User我们需要new一个User然后才能使用
下面我们通过Dragger2去完成上述过程
-
依赖注入方
通过@Inject和@Module&&@Provide可以去完成依赖注入方
先讲@Module&&@Provide
我们在TestUser 中想使用User那么我们需要一个Model我们的@Model是用在类上的。
我们创建了一个@Module TestUserModule@Module public class TestUserModule { @Provides User provideUser(){ return new User(); } }
我们通过上述代码就完成的依赖注入方。这里解释一下@Module是一个依赖提供方的合集,本身一般是不作为内容被提供的。User才是我们需要提供的内容
比如我们现在希望TestUserModule 同时提供一个Account
@Module
public class TestUserModule {
@Provides
User provideUser(){
return new User();
}
@Provides
Account provideAccount(){
return new Account();
}
}
-
依赖注入容器
依赖注入容器只是一个接口,用来描述被注入的对象TestUser 需要哪些modules = TestUserModule.class
@Component(modules = TestUserModule.class)
public interface TestUserComponent {
void inject(TestUser testUser);
}
注入容器本身只是一个接口interface -
依赖需求方
public class TestUser {
@Inject
User user;
public static void main(String[] arg) {
TestUser testUser = new TestUser();
DaggerTestUserComponent.builder().build().inject(testUser);
System.out.println(testUser.user.name);
}
}
我们要打印出name System.out.println(testUser.user.name);
在使用User前要做两件事情
- DaggerTestUserComponent.builder().build().inject(testUser);
DaggerTestUserComponent是在编译后编译器帮我们生成的。生成的格式是Dagger+我们自定义的容器 - @Inject
User user;
通过我们刚刚的DaggerTestUserComponent.builder().build().inject(testUser);Dagger2会帮我们把user初始化。
注意事项
@Module
Dagger2是怎么选择依赖提供的呢,规则是这样的:
步骤1:查找Module中是否存在创建该类的方法。
步骤2:若存在创建类方法,查看该方法是否存在参数
步骤2.1:若存在参数,则按从步骤1开始依次初始化每个参数
步骤2.2:若不存在参数,则直接初始化该类实例,一次依赖注入到此结束
步骤3:若不存在创建类方法,则查找Inject注解的构造函数,看构造函数是否存在参数
步骤3.1:若存在参数,则从步骤1开始依次初始化每个参数
步骤3.2:若不存在参数,则直接初始化该类实例,一次依赖注入到此结束