Dagger2 依赖注入使用和分析

1. Dagger2是什么

Dagger2 依赖注入使用和分析_第1张图片
er~~

1.1 依赖注入(Dependency Injection)

  • 一种软件设计原则,为对象提供了所需要的依赖
  • 依赖如果由外部注入进来,更容易被重用

1.2 Dagger2简介

在我们开发过程中,所需使用的对象往往需要依赖其它的对象。比如:
我们使用Retrofit来创建HTTP请求对象时,那么Retrofit还需要一个Gson之类的解析库,以及需要依赖OkHttpClient对象,而OkHttp可能还需要一个Cache 对象,可见,创建一个Retrofit的对象是一个很繁琐的过程。
Dagger2简化了这个过程。我们使用注解来标注依赖之间的关系,Dagger2通过分析注解来生成代码,使依赖关联起来。

  • Dagger2是由谷歌维护的一款Java依赖注入框架,由 square 的 Dagger1 flok而来。
  • 出于性能考虑,Dagger2不使用反射,注解都是在编译时处理
  • 使用Java 依赖注入标准(JSR-330,Dependency Injection for Java)规范,

2. Dagger2怎么用:HelloWord

  • 添加android-apt插件,首先在根结点的build.gradle加一行依赖

 dependencies {
     ...
     classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
 }
  • 然后在app/build.gradle中上加插件和Dagger2依赖

apply plugin: 'com.neenbedankt.android-apt'
 ...
dependencies {
    ...
    apt 'com.google.dagger:dagger-compiler:2.2'
    compile 'com.google.dagger:dagger:2.2'

    provided 'org.glassfish:javax.annotation:10.0-b28'
}
  • 好,现在我们来写一个 HelloWorld 程序,从外部注入一个"Hello World!"MainActivity,首先我们需要一个Module 用来提供所需的依赖:
@Module
public class HelloModule {
    @Provides @Singleton  
    public String providesHelloMessage() {
        return "Hello World!";  
    }
}
  • 然后我们使用Component来标注MainActivityHelloModule之间的关系,我们只需要定义这样一个接口,它的实现类会由Dagger2编译后生成:
@Singleton
@Component(
    modules = HelloModule.class
)
public interface HelloComponent {
  void inject(MainActivity activity);
}
  • 执行编译操作让Dagger2生成HelloComponent的实现类DaggerHelloComponent,最后就可以在MainActivity中注入了:
public class MainActivity extends AppCompatActivity {
  @Inject String helloMessage;

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    HelloComponent component = DaggerHelloComponent.builder()
        .helloModule(new HelloModule(this))
        .build();
    component.inject(this);
  }
}

嗯,这样HelloModule中的Hello World!字符串就被注入到MainActivity中的helloMessage了,不信你打印出来看看。

  • Demo源码:dagger2-demo-helloworld

3. Dagger2 分析

  • 以上HelloWorld的例子,由这几个部分组成:


    Dagger2 依赖注入使用和分析_第2张图片
    HelloWord

@Module 和 @Provides

首先我们要定义要用到的依赖,这些依赖就放在一个被@Module标记的类里面。这个类定义了一些方法,每一个方法就是一个工厂,提供所需要的依赖,用@Provides标记。

@Component

Dagger2通过@Component来生成代码,Dagger2会生成一个以Dagger开头的类(比如,DaggerHelloComponent),它负责实例化所需要的依赖。

@Inject

@Inject 用来声明要被注入的对象,Dagger2通过查找自己的依赖关系,找出和这个对象匹配的返回类型并分配给它,最终这个对象就是之前在@Module中定义的那个对象。

  • 这里可能会有疑问,Dagger2是通过类型来查找的,如果有两个类型相同的依赖怎么办?
    答:使用Qualifier来区分不同的类型。例如:
@Inject @Named("cached") OkHttpClient client;@Inject @Named("non_cached") OkHttpClient client2;

上面代码中的@Named就是 Dagger2 定义好的一个 Qualifier。我们也可以自己定义 Qualifier:

@Qualifier
@Documented
@Retention(RUNTIME)
public @interface DefaultOkHttp {
}

@Singleton

Dagger2 中可以通过自定义 Scope 注解来指定它的作用范围。如果一个对象的作用范围指定为@Singleton的话,则是全局唯一的,当应用销毁时才会被销毁。关于自定义 Scope 的更多详细内容可以参考这篇文章:http://frogermcs.github.io/building-userscope-with-dagger2


看了上面的分析,希望大家有所帮助,并且把 Dagger2 用起来,如果有不明白的,欢迎留言交流。

Dagger2 依赖注入使用和分析_第3张图片
公众号

你可能感兴趣的:(Dagger2 依赖注入使用和分析)