dagger2源码简析

2017/11/13 源码分析

介绍

关于dagger github上是这样介绍的。

A fast dependency injector for Android and Java. Android和Java的快速依赖注入器。

栗子

dagger2有很多用法,本文用最一个简单的使用方法所生成的源码来进行剖析。首先把我们的栗子代码贴出来:

public class Persion {
    public void sayHello(){
        System.out.println("hello");
    }
}

@Module
public class PersionModule {
    @Provides
    public Persion providePersion(){
        return new Persion();
    }
}

@Component(modules = PersionModule.class)
public interface HelloActivityComponent {
    void inject(HelloDaggerActivity activity);
}

public class HelloDaggerActivity extends Activity {
    @Inject
    Persion mPersion;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DaggerHelloActivityComponent.create().inject(this);
        setContentView(R.layout.activity_hello);
        mPersion.sayHello();
    }
}

源码简析

接下来编译,来看apt生成的三个文件: dagger生成文件.png

我们从 DaggerHelloActivityComponent.create().inject(this); 注入依赖的方法口入开始分析。DaggerHelloActivityComponent代码如下:

public final class DaggerHelloActivityComponent implements HelloActivityComponent {
  private PersionModule persionModule;

  private DaggerHelloActivityComponent(Builder builder) {
    initialize(builder); //4
  }

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

  public static HelloActivityComponent create() {
    return new Builder().build(); //1
  }

  @SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {
    this.persionModule = builder.persionModule; //5
  }

  @Override
  public void inject(HelloDaggerActivity activity) {
    injectHelloDaggerActivity(activity);//6
  }

  private HelloDaggerActivity injectHelloDaggerActivity(HelloDaggerActivity instance) {
    HelloDaggerActivity_MembersInjector.injectMPersion(//7
        instance,
        Preconditions.checkNotNull(
            persionModule.providePersion(),
            "Cannot return null from a non-@Nullable @Provides method"));
    return instance;
  }

  public static final class Builder {
    private PersionModule persionModule;

    private Builder() {}

    public HelloActivityComponent build() {
      if (persionModule == null) {
        this.persionModule = new PersionModule();//2
      }
      return new DaggerHelloActivityComponent(this);//3
    }

    public Builder persionModule(PersionModule persionModule) {
      this.persionModule = Preconditions.checkNotNull(persionModule);
      return this;
    }
  }
}

注释1create方法调用了new Builder().build();这个建造者方法。注释2中可以看到这个建造者方法创建了我们提供的PersionModule类的对象,并在注释3中返回了DaggerHelloActivityComponent 类对象传入了当前builder对象。注释4的构造方法执行了initialize ()初始化方法,然后在注释5中初始化了module对象为builder中创建的module对象。接下来执行注释6inject()然后执行到到注释7injectHelloDaggerActivity()方法HelloDaggerActivity_MembersInjector.injectMPersion( instance, Preconditions.checkNotNull( persionModule.providePersion(), "Cannot return null from a non-@Nullable @Provides method")); 此处执行HelloDaggerActivity_MembersInjector.injectMPersion ()方法,传入了两个参数,一个instance我们的需要被注入依赖的目标类HelloDaggerActivity对象,另外一个是persionModule.providePersion() 方法也就是我们编写的PersionModule类返回new Persion()

贴上HelloDaggerActivity_MembersInjector类源码如下:

public final class HelloDaggerActivity_MembersInjector
    implements MembersInjector<HelloDaggerActivity> {
  private final Provider<Persion> mPersionProvider;

  public HelloDaggerActivity_MembersInjector(Provider<Persion> mPersionProvider) {
    this.mPersionProvider = mPersionProvider;
  }

  public static MembersInjector<HelloDaggerActivity> create(Provider<Persion> mPersionProvider) {
    return new HelloDaggerActivity_MembersInjector(mPersionProvider);
  }

  @Override
  public void injectMembers(HelloDaggerActivity instance) {
    injectMPersion(instance, mPersionProvider.get());
  }

  public static void injectMPersion(HelloDaggerActivity instance, Persion mPersion) {
    instance.mPersion = mPersion; //1
  }
}

此处注释1中将persion对象设置到activity中。至此我们HelloDaggerActivity所依赖的mPersion对象就注入到了目标类HelloDaggerActivity中。终于可以愉快的玩耍了~~~

Search

    Table of Contents