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<Tyre> {
  INSTANCE;

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

  public static Factory<Tyre> create() {
    return INSTANCE;
  }
}
然后我们看一下Car_MembersInjector
public final class Car_MembersInjector implements MembersInjector<Car> {
  private final Provider<Tyre> typeProvider;

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

  public static MembersInjector<Car> create(Provider<Tyre> 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<Tyre> typeProvider) {
    instance.type = typeProvider.get();
  }
}

我们来看一下上面定义的Component接口
@Component
public interface CarComponent {
    void injectCar(Car car);
}
其实他会生成一个桥接类
public final class DaggerCarComponent implements CarComponent {
  private MembersInjector<Car> 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注解的方法提供对象
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值