深入理解Dagger2,初识依赖注入。
首先感谢定义域的文章, 让我深入理解了依赖注入。
依赖注入是什么
没有依赖注入之前,我们是这样写代码的:
public class A {
public String name = "A";
public A() {
}
public void sayHello() {
System.out.println(tag);
}
}
public class B {
public String name = "B";
private A a;
public B(A a) {
this.a = a;
}
public void sayHello() {
System.out.println("你好" + a.name + ", 我是" + name);
}
}
public class Container {
public static void main(String[] args) {
B b = new B(new A());
b.sayHello();// "你好A, 我是B"
}
}
这样B类就实现了依赖A类.这是通过构造器来提供依赖,创建b对象的时候,通过构造器传入b来实现依赖。比这个更”高级”的方法是通过工厂方法,代码如下:
public class A {
public String name = "A";
public A() {
}
public void sayHello() {
System.out.println(tag);
}
}
public class AFactory {
public static A newA() {
return new A();
}
}
public class B {
public String name = "B";
private A a;
public B(A a) {
this.a = a;
}
public void sayHello() {
System.out.println("你好" + a.name + ", 我是" + name);
}
}
public class Container {
public static void main(String[] args) {
B b = new B(AFactory.newA());
b.sayHello();// "你好A, 我是B"
}
}
相信以上初级的程序猿也都能懂, 其实上面两种方式都是实现同样的功能(获取A对象), 目前获取依赖的方式大概分为四种:
- 构造器
- 工厂方法
- 服务定位器
- 依赖注入
在我们的程序中, 总有某种类型依赖于其他类型。类型少, 我们可以通过简单的构造器来实现这种依赖的初始化, 一旦类型依赖复杂, 那么构建这种依赖关系就成了问题。
JSR-330
JSR-330定义了如何使用依赖的一套标准。具体关于JSR-330可以参考定义域的这篇文章
Javax.inject包下给我们提供了以注解方式实现的一整套使用方式, 跟JSR-330一样,也没有定义配置方式和实现方式。
Dagger2基础
Dagger2实现了JSR-330。是采用代码生成方式来实现依赖注入器。采用注解方式来配置。Dagger2依赖的配置包含如下:
- @Inject 标识可注入的,可以是构造器、字段、方法。这个注解是在Java标准中定义的。
- @Module 标识这个类是提供依赖的类, 与@provides搭配使用.它是Dagger2中定义的。
- @provides 标识方法是提供依赖的方法, 与@Module搭配使用.它是在Dagger2中定义的。
- @Component 标识类是依赖注入器类, 它也是在Dagger2中定义的。
- @Scope 作用域
- @Singleton 单例作用域
- @Qualifier 创建自定义限定器
- @Named 字符串限定器
注解整个注入过程如下图: