Dagger2源码解析

1、背景

Dagger2是一个依赖注入框架能让项目进行解耦合,现在Dagger2在项目中被广泛使用特别是结合MVP架构使用,非常典型的降低耦合,因为在MVP模式只能中Activity持有presenter的引用,同时presenter又持有view的引用,这样便于更新UI界面,这样Activity和Presenter就耦合在一起了,而dagger注入可以有效解耦合

2、基础使用

1.添加依赖
    implementation 'com.google.dagger:dagger:2.4'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.4'

2.学习@Inject

2.2.1.@Inject一个是标记在需要依赖的变量上,使用在构造函数上
基础使用
public class Tyre {

    @Inject
    public Tyre() {

    }
}

@Component
public interface CarComponent {
    void injectCar(Car car);
}
public class Car {
    @Inject
    Tyre type;
    public Car() {
        DaggerCarComponent.builder().build().injectCar(this);
    }
}

这样我们就把Tyre给生产出来了

我们来看实现原理

3、实现原理

我们通过make project会在工程下的build/generated/source/下面找到几个自动创建的辅助类 首先我们看第一个Tyre_Factory 这个是因为

    @Inject
    public Tyre() {
    }

生成的一个 方法就是一个初始化对象 一个是

public enum Tyre_Factory implements Factory {
  INSTANCE;

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

  public static Factory create() {
    return INSTANCE;
  }
}

然后我们看一下Car_MembersInjector

public final class Car_MembersInjector implements MembersInjector {
  private final Provider typeProvider;

  public Car_MembersInjector(Provider typeProvider) {
    assert typeProvider != null;
    this.typeProvider = typeProvider;
  }

  public static MembersInjector create(Provider typeProvider) {
    return new Car_MembersInjector(typeProvider);
  }

  @Override
  public void injectMembers(Car instance) {//注意一下这个方法
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    instance.type = typeProvider.get();
  }

  public static void injectType(Car instance, Provider typeProvider) {
    instance.type = typeProvider.get();
  }
}

我们来看一下上面定义的Component接口

@Component
public interface CarComponent {
    void injectCar(Car car);
}

其实他会生成一个桥接类

public final class DaggerCarComponent implements CarComponent {
  private MembersInjector carMembersInjector;

  private DaggerCarComponent(Builder builder) {
    assert builder != null;
    initialize(builder);
  }

  public static Builder builder() {
    return new Builder();
  }

  public static CarComponent create() {
    return builder().build();
  }

  @SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {

    this.carMembersInjector = Car_MembersInjector.create(Tyre_Factory.create());
  }

  @Override
  public void injectCar(Car car) {
    carMembersInjector.injectMembers(car);
  }

  public static final class Builder {
    private Builder() {}

    public CarComponent build() {
      return new DaggerCarComponent(this);
    }
  }
}

然后我们看看一下调用方法

    public Car() {
        DaggerCarComponent.builder().build().injectCar(this);
    }


看到这里我们就知道了简单使用的原理了首先我们定义一个type在构造方法中加入@inject注解 它会生成一个Tyre_Factory类 其实就是一个provider,然后在Car中的变量中加入@inject注解,那么就会生成一个Car_MembersInjector类 ,然后我们定义了一个借口 这个接口加入了@Component注解,然后有定义 injectCar(Car car);方法 ,这个接口就会生成一个叫DaggerCarComponent的辅助类 这个类是串联上面的Tyre_Factory和Car_MembersInjector这两个类的,我们看一下在Car构造方法中调用了 DaggerCarComponent.builder().build().injectCar(this);这一套方法,其实点进去就是通过建造者模式将Tyre_Factory传给了Car_MembersInjector作为Provider然后将需要创建type的car对象传进去通过调用Car.type=Tyre_Factory的create方法创建type对象给联系起来实现对象的创建。

4、 @Module和@Provide

这两个注解是使用在你无法直接new这个类的时候比如我无法改变系统类的源码,那我可以使用这种@Module+@Provides的方式来创建一个


@Module
public class ComputerModule {

    @Provides
     Computer provideComputer(){
        return new Computer();
    }
}

定义一个接口实现类

@Component(modules = ComputerModule.class)
public interface ComputerComponent {
    void injectComputer(ComputerModule computer);
}

我们就可以实现创建Computer这个类了,具体为什么可以实现Computer原理跟上面也是类似的原理只不过最终调用ComputerModule的 @Provides注解的方法提供对象

你可能感兴趣的:(Android)