什么是依赖注入呢?

直接采用@声明的方式,而不是new,依赖注入干嘛的,省却new的,就是为了不用new 用的,但是使用场景受限,

通过构造器或者其他方法传入依赖的对象就是依赖注入,这样就不需要在一个模块中去创建另外一个模块了。对象是在别的地方被创建然后通过构造器传入依赖它的对象中

什么是依赖注入器?

你可以把他想象成一个这样的模块,它负责构造所有其他模块的实例,并且传入这些模块的依赖。现在我们的应用程序中只有一个入口来负责创建所有模块的实例,而这个入口完全在我们的控制下。

什么是Dagger

Dagger是 一个完全为低端设备设计的依赖注入器。绝大多数的依赖注入器都是基于反射来实现的。反射的确很酷,但是在低端设备上执行反射的效率太低。Dagger使用 的是预编译技术来创建所有依赖的类。这样就避免了使用反射。Dagger虽然没有其他的依赖注入框架强大,但它是效率最高的。

为什么有些Module必须通过参数实例化如Activity– 不能依赖就要provide

activity.MainActivity cannot be provided without an @Inject constructor or from an @Provides-annotated method.

因为Activity正常情况下不会编写构造函数,因而也就无法通过@Inject构造函数实例化,只能通过@Provides提供,所以,component在依赖Module里面必须相应的提供,创建Module的时候,也必须把Activity引用传递过去。因为依赖是层层递归的,因此必要要将需要的依赖模块实例化。

singletone是否需要配合使用

什么时候需要返回值

public interface AppComponent {


    Application getApplication();

    ApiService getApiService();

    User getUser();
    }

根据返回值,方法名随便写

scope的一些理解总结

scope只能有一个

scope只是为编译提供一些约束,如果scope不一一对应是无法编译通过的,singleton也仅仅是一个scope的annotation,本身没有实现单利的能力,仍然可以实现度多个component与module,只是application的实例要通过类似单利的模型来提供,总的来说,还是程序自身来保证单利模式。

provider方法提供的是单利–不会重复调用provider的provide方法

  @SuppressWarnings("unchecked") // cast only happens when result comes from the factory
  @Override
  public T get() {
    // double-check idiom from EJ2: Item 71
    Object result = instance;
    if (result == UNINITIALIZED) {
      synchronized (this) {
        result = instance;
        if (result == UNINITIALIZED) {
          instance = result = factory.get();
        }
      }
    }
    return (T) result;
  }

dagger2实现原理–从APT实现代码剖析

DaggerDaggerActivityComponent

  private Provider<String> provideClassNameProvider;
  private Provider<User> provideUserProvider;
  private Provider<Activity> provideDaggerActivityProvider;
  private Provider<DaggerActivityPresenter> daggerActivityPresenterProvider;
  private MembersInjector<DaggerActivity> daggerActivityMembersInjector;
  private MembersInjector<MainActivity> mainActivityMembersInjector;

  private void initialize(final Builder builder) {  
    this.provideClassNameProvider = ScopedProvider.create(DaggerActivityModule_ProvideClassNameFactory.create(builder.daggerActivityModule));
    this.provideUserProvider = ScopedProvider.create(DaggerActivityModule_ProvideUserFactory.create(builder.daggerActivityModule));
    this.provideDaggerActivityProvider = ScopedProvider.create(DaggerActivityModule_ProvideDaggerActivityFactory.create(builder.daggerActivityModule));
    this.daggerActivityPresenterProvider = DaggerActivityPresenter_Factory.create(provideDaggerActivityProvider);
    this.daggerActivityMembersInjector = DaggerActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideClassNameProvider, provideUserProvider, daggerActivityPresenterProvider);
    this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUserProvider);
  }

provide之间是相互依赖的,Provide应该是先生成不需要参数的,再生成需要参数的

  @Override
  public void Inject(DaggerActivity activity) {  
    daggerActivityMembersInjector.injectMembers(activity);
  }

  @Override
  public void Inject(MainActivity activity) {  
    mainActivityMembersInjector.injectMembers(activity);
  }

Qualifier(限定符)就是解决依赖注入迷失

如果一个类在同一方式下有多个创建类的方法的时候,Component会选取哪个方法来创建这个类的实例呢?举个例子

@Module
public class Module{

      @Provides
      A provideA(){
        return A();
      }

      @provides
      A provideOtherA(){
             return A();
      }
} 如果我们按照上面这样写,Dagger2在编译的时候就会报错,那么我们改如何解决呢?这时候就需要用到@Qualifier了,我们可以用这个注解给不同的创建实例的方法进行标识并加以区分。

@Module
public class Module{

      @Named("firstA")
      @Provides
      A provideFirstA(){
           return A();
      }

      @Named("secondA")
      @provides
      A provideSecondA(){
             return A();
      }
} @Named是Dagger2对于@Qualifier一个默认实现,我们也可以自定义,比如@ForApplication和@ForAcitivity来标识不同的Context

@Qualifier @Documented @Retention(RUNTIME) public @interface Named {

/** The name. */
String value() default ""; } 这样,通过@Named我们就可以区分不同的实例了

public class Human{
   @Inject
   @Named("firstA")
   A firstA;

   @Named("secondA")
   @provides
   A secondA;
}

参考文档

使用Android依赖注入工具Dagger(一) Android:dagger2让你爱不释手-基础依赖注入框架篇 Android:dagger2让你爱不释手
Android:dagger2让你爱不释手
Android:dagger2让你爱不释手