dagger2从不懂到入门

dagger的目的是实现依赖注入

1、什么是依赖注入

举例:

不是依赖注入的例子:

class Person{

  void playGame(){

    Football football = new Football;

    football.play();

  }

}

是依赖注入的例子:

class Person{

  void playGame(Football football){

    football.play();

  }

}

2、为什么需要dagger

其实你可以不需要它,你手动按照上述方式注入也是可以的。但如果你不想手动,而且想实现依赖注入而且不用写很多的代码就能正确的实现它,那你需要dagger。

3.我该如何使用dagger

首先你要对依赖注入这四个字有更深入的理解。

既然想通过依赖注入来完成你的开发,所以你应当知道它主要就是两点。

a.依赖从哪里来

b.我将如何注入(设置、传给)进去

通常的,依赖来自于new XXX(),而且注入的方式是构造函数(Person(String name))或直接设置(Person.name)。

所以dagger也不可避免的需要实现这两点,为了达到机器代替人工的目的,以及良好的拓展,

而作为开发者只需要 写接口 加注解 即可。

首先,dagger给我们提供了两种方式来实现依赖从哪里来,

1.在需要被注入的类的构造函数中加上@Inject注解

或2.实现一个Module类,在类上面加上@Module注解,并且,需要提供若干个返回需要被注入的类的方法,这些方法都要加上@Provider注解

举例说明:

public class Child{

  @Inject

  public Child(){

  }

}

 

@Module

public class MyModule{
  

  @Provider

  public Parent providerParent(){

    return new Parent();

  }
}

然后,为了将这些需要被注入的类注入进入,需要做以下工作:

1.创建一个抽象类或接口 注解为@Compoment,并且需要在注解的参数里加上能够提供需要注入的Module类的名称。

2.对需要注入的类A的构造函数或成员加上@Inject注解,注意如果是在成员上加的,需要注意在Compoment接口或抽象类中添加一个方法,这个方法的参数只有一个,就是A。

举例说明:

@Compoment(module={MyModule.class})

public interface MyComponent{

  

}

 

public class Family{

  @Inject Child child;

  @Inject

  public Family(Parent parent)

}

 

最后,在编译期,dagger会为我们生成多个类,其中有一个针对Component类的实现DaggerCompoment,

我们需要在恰当的时候(应是趁早)使用它,

使用方式大概是DaggerComponent.builder().xxxx.build();如果里面有方法可能还需要加上injectxxx()。

举例说明:
为了实现child 注入到Family我们需要在MyComponent补充一个方法:

@Compoment(module={MyModule.class})

public interface MyComponent{

  public void injectToFamily(Family family);

}

然后编译完成后,会自动生成DaggerMyComponent实现类

然后在想使用Family之前,切记需要调用

DaggerMyComonent.builder().build().injectToFamily(???)

困难出现了,我们没有办法直接创建Family的实例,因为我们想通过dagger获取,

为了获取到Family实例,需要在MyCompoment再添加一个方法

@Compoment(module={MyModule.class})

public interface MyComponent{

  public void injectToFamily(Family family);

  public Family getFamily();

}

这样的话

MyComponent compoment = DaggerMyComonent.builder().myModule(new MyModule())build();

family = compoment.getFamily();
compoment.injectToFamily(family);

尘埃落定。

 

4.为什么这样可以实现依赖注入

dagger的做法是统一规范,创建与注入隔离;

首先在dagger中,一切被注入的对象的获取都是从Provicer<T> 接口的get方法中来.

为了实现这种统一的效果,dagger给每个这种对象的获取都建立了单独的工厂类,

通过@Inejct构造器来提供对象的---->Person_Facatory

看一下它是如何实现的:

public final class Person_Factory implements Factory<Person> {
private static final Person_Factory INSTANCE = new Person_Factory();

@Override
public Person get() {
return new Person();
}

public static Factory<Person> create() {
return INSTANCE;
}

/** Proxies {@link Person#Person()}. */
public static Person newPerson() {
return new Person();
}
}

注意 :

public interface Factory<T> extends Provider<T> {
}

在需要的地方调用
Person_Factory.create().get()即可

如果对象获取来自于Module,
dagger为每个在Module里的方法都增加了工程类
譬如 MyModule_getPersonFactory,两者套路差不多.

然后注入的过程发生在被注入对象的实例获取时(大部分);

MyComponent compoment = DaggerMyComonent.builder().myModule(new MyModule())build();

family = compoment.getFamily();//在getFamily调用的时候所依赖额对象也在完成创建。

而实现的思路也是先获取到创建Family的工厂,然后调用它的get方法.



posted @ 2018-04-25 10:29  lightverse  阅读(127)  评论(0编辑  收藏  举报