dagger2原始碼簡析

zyl409214686發表於2017-12-23

介紹

關於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中。終於可以愉快的玩耍了~~~

相關文章