Dagger官方文档

Dagger

为Android和Java打造的依赖注入框架

简介

使用Dagger

我们将使用一个咖啡机的例子来展示依赖注入和Dagger。

声明依赖

Dagger创建一个你的应用的实例并且满足他们的依赖。它使用javax.inject.Inject 注解来标明哪个构造函数或者成员属性是它感兴趣的。
使用@Inject来注解一个Dagger用来创建一个实例的构造方法。当一个新的实例被申请的时候,Dagger就会获取到请求参数值并且调用构造方法。

class Thermosiphon implements Pump {
  private final Heater heater;

  @Inject
  Thermosiphon(Heater heater) {
    this.heater = heater;
  }

  ...
}

Dagger也可以直接注入属性。下面这个例子直接为pump属性和heater属性分别获取了一个实例。

class CoffeeMaker {
  @Inject Heater heater;
  @Inject Pump pump;

  ...
}

如果你的类只有被 @Inject 标注的属性,但是却没有被其标注的构造方法,Dagger将使用无参构造方法(如果它存在的话)。缺少@Inject标注的类不能被Dagger构建。
Dagger不支持方法注入。

满足依赖

一般来讲,Dagger会使用上述方式来构造一个对应请求类型的实例,以此来满足依赖。当你请求了一个CofferMaker,将会调用new CofferMaker()并把它关联到属性中。

但是 @Inject 不能在以下情况工作:

  • 接口不能被构造
  • 第三方类不能被构造
  • 要注册的对象必须已经标注过!

在这种情况下尴尬的情况下,可以使用 @Provides 注解一个方法来满足依赖。方法的返回值定义了它将满足的依赖。
举个例子,provideHeater()将在Heater被请求时调用:

@Provides Heater provideHeater() {
  return new ElectricHeater();
}

被@Provides标注的方法也有可能有他们自己的依赖。当请求一个Pump的时候,这个方法返回一个 Thermosiphon 。

@Provides Pump providePump(Thermosiphon pump) {
  return pump;
}

所有的 @Provides的方法属于module。这是一个被@Module标注的类:

@Module
class DripCoffeeModule {
  @Provides Heater provideHeater() {
    return new ElectricHeater();
  }

  @Provides Pump providePump(Thermosiphon pump) {
    return pump;
  }
}

依照惯例,@Provides方法一般会有一个provide前缀,Module类一般会有一个Module后缀。

创建图

被@Inject 和 @Provides标注的类之间的依赖关系,可以使用一个对象图来表示。可以使用ObjectGraph.create()来获取这个图,其可以接收一个或者多个module。

ObjectGraph objectGraph = ObjectGraph.create(new DripCoffeeModule());

为了这个图能使用,我们需要去引导注入(bootstrap injection)。一般会在命令行程序中的main类中,或者在一个Android App的Activity中请求注入。在我们咖啡机的示例程序中,CoffeeApp类被用来启动依赖注入。我们让图来提供一个注入的示例:

class CoffeeApp implements Runnable {
  @Inject CoffeeMaker coffeeMaker;

  @Override public void run() {
    coffeeMaker.brew();
  }

  public static void main(String[] args) {
    ObjectGraph objectGraph = ObjectGraph.create(new DripCoffeeModule());
    CoffeeApp coffeeApp = objectGraph.get(CoffeeApp.class);
    ...
  }
}

只剩一件事还没做了,那就是图还不知道CoffeeApp类。我们需要像注册一个module一样显示地注册它:

@Module(
    injects = CoffeeApp.class
)
class DripCoffeeModule {
  ...
}

注入操作将会在编译期就让图生效。以此来发现一些问题。(Detecting problems early speeds up development and takes some of the danger out of refactoring.)
现在图已经被建立起来,而且根对象也被注入了,我们来运行一下我们的咖啡机。好玩吧。

$ java -cp ... coffee.CoffeeApp
~ ~ ~ heating ~ ~ ~
=> => pumping => =>
 [_]P coffee! [_]P

你可能感兴趣的:(Dagger官方文档)