Dagger2 生成代碼學習筆記

上一篇記錄了如何使用Dagger,其中還漏了一些內容,回頭再補。今天來看看Dagger在預編譯時期生成的輔助代碼,看看Dagger做依賴注入的實現原理是咋樣的。
還是從上一篇中最簡單的Sample開始。先看下代碼:
MainActivity:

public class MainActivity extends AppCompatActivity {

    @Inject
    UserModel user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerUserComponent.builder()
                .userModule(new UserModule())
                .build()
                .inject(this);

        ((TextView) findViewById(R.id.text_view)).setText("Name:" + user.getName() + "::Age:" + user.getAge());
    }
}

UserModel:

public class UserModel {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

UserModule:

@Module
public class UserModule {

    UserModule() {}

    @Provides
    UserModel provideUsers() {
        UserModel user = new UserModel();
        user.setName("lala");
        user.setAge(18);
        return user;
    }
}

UserComponent:

@Component(modules = {UserModule.class})
public interface UserComponent {
    void inject(MainActivity mainActivity);
}

運行結果如下:


Screenshot_2017-02-08-11-40-46.png

OK,咱們先來看看Dagger為我們上面的代碼生成了哪些東東。
咱們自己的類:
1.MainActivity
2.UserComponent
3.UserModel
4.UserModule
Dagger生成的類:
1.DaggerUserComponent
2.UserModule_ProvideUsersFactory
3.MainActivity_MembersInjector
好,下面來逐個看看這幾個生成類

直接從我們執行注入的代碼下手:

DaggerUserComponent.builder()
                .userModule(new UserModule())
                .build()
                .inject(this);

可以看到,我們通過Builder方式,傳一個UserModule的實例,build一個DaggerUserComponent的實例出來,然后調用 inject 方法執行注入操作。
下面嘍一眼DaggerUserComponent的代碼。
DaggerUserComponent:

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerUserComponent implements UserComponent {
  private Provider<UserModel> provideUsersProvider;
  private MembersInjector<MainActivity> mainActivityMembersInjector;

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

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

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

  private void initialize(final Builder builder) {  
    this.provideUsersProvider = UserModule_ProvideUsersFactory.create(builder.userModule);
    this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
  }

  @Override
  public void inject(MainActivity mainActivity) {  
    mainActivityMembersInjector.injectMembers(mainActivity);
  }

  public static final class Builder {
    private UserModule userModule;
  
    private Builder() {  
    }
  
    public UserComponent build() {  
      if (userModule == null) {
        this.userModule = new UserModule();
      }
      return new DaggerUserComponent(this);
    }
  
    public Builder userModule(UserModule userModule) {  
      if (userModule == null) {
        throw new NullPointerException("userModule");
      }
      this.userModule = userModule;
      return this;
    }
  }
}

這個類非常簡單,它實現了咱們寫的UserComponent接口,實現了inject方法。重點在初始化 (initialize) 和注入 (inject) 兩個方法。

private Provider<UserModel> provideUsersProvider;
private MembersInjector<MainActivity> mainActivityMembersInjector;

private void initialize(final Builder builder) {  
    this.provideUsersProvider = UserModule_ProvideUsersFactory.create(builder.userModule);
    this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
  }

可以看到,initialize這個方法創建了兩個成員變量,provideUsersProvidermainActivityMembersInjector
創建Provider的代碼引出了第二個生成類: UserModule_ProvideUserFactory

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class UserModule_ProvideUsersFactory implements Factory<UserModel> {
  private final UserModule module;

  public UserModule_ProvideUsersFactory(UserModule module) {  
    assert module != null;
    this.module = module;
  }

  @Override
  public UserModel get() {  
    UserModel provided = module.provideUsers();
    if (provided == null) {
      throw new NullPointerException("Cannot return null from a non-@Nullable @Provides method");
    }
    return provided;
  }

  public static Factory<UserModel> create(UserModule module) {  
    return new UserModule_ProvideUsersFactory(module);
  }
}

顧名思義,UserModule_ProvideUsersFactory 是一個工廠類,此類用來生產我們用 @Inject 注解的UserModel實例。
上面這句是屁話,UserModel的真正的實例并不在這里生產,可以看到,這個“偽工廠”接受一個咱們寫的UserModule的實例,然后在get方法中調用UserModule的provideUsers()方法(咱們自己寫的),把拿到的UserModel實例返回。
咱們回到DaggerUserComponent,再瞄一眼初始化的第一句代碼:
this.provideUsersProvider = UserModule_ProvideUsersFactory.create(builder.userModule);
在這里創建了一個生產UserModel實例的工廠實例。該實例的get方法返回一個UserModel的實例(從Module的provide方法中拿到的)。
OK,拿到了Provider的實例,來看看初始化的第二行代碼:
this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
這里引出了第三個生成類,MainActivity_MembersInjector.

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
  private final MembersInjector<AppCompatActivity> supertypeInjector;
  private final Provider<UserModel> userProvider;

  public MainActivity_MembersInjector(MembersInjector<AppCompatActivity> supertypeInjector, Provider<UserModel> userProvider) {  
    assert supertypeInjector != null;
    this.supertypeInjector = supertypeInjector;
    assert userProvider != null;
    this.userProvider = userProvider;
  }

  @Override
  public void injectMembers(MainActivity instance) {  
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    supertypeInjector.injectMembers(instance);
    instance.user = userProvider.get();
  }

  public static MembersInjector<MainActivity> create(MembersInjector<AppCompatActivity> supertypeInjector, Provider<UserModel> userProvider) {  
      return new MainActivity_MembersInjector(supertypeInjector, userProvider);
  }
}

MainActivity_MembersInjector的create方法接收兩個參數,生成一個實例返回。這個類實現了MembersInjector接口,實現了injectMembers方法,咦?
instance.user = userProvider.get();
真相只有一個,這一句才是真正執行注入的代碼。從接收到的Provider實例中通過調用get方法拿到UserModel實例,并賦給傳進來的MainActivity實例的user成員變量。這也是為什么我們用 @Inject 注解的變量不可以是private的原因。
所以這么看下來,注入過程還是很簡單的,像很多文章說的那樣,There is no magic with Dagger.
就在飄飄然的時候,瞄見了這句代碼
supertypeInjector.injectMembers(instance);
supertypeInjector?這個是初始化的時候創建塞進來的:

this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);

注意這里有兩個長得很像的類,MembersInjector 和 MembersInjectors,臥槽。
MembersInjector是一個接口,就是上面提到的那個,里面只有一個injectMembers抽象方法。那MembersInjectors是什么鬼...

public final class MembersInjectors {
  /**
   * Returns a {@link MembersInjector} implementation that injects no members
   *
   * <p>Note that there is no verification that the type being injected does not have {@link Inject}
   * members, so care should be taken to ensure appropriate use.
   */
  @SuppressWarnings("unchecked")
  public static <T> MembersInjector<T> noOp() {
    return (MembersInjector<T>) NoOpMembersInjector.INSTANCE;
  }

  private static enum NoOpMembersInjector implements MembersInjector<Object> {
    INSTANCE;

    @Override public void injectMembers(Object instance) {
      if (instance == null) {
        throw new NullPointerException();
      }
    }
  }

  /**
   * Returns a {@link MembersInjector} that delegates to the {@link MembersInjector} of its
   * supertype.  This is useful for cases where a type is known not to have its own {@link Inject}
   * members, but must still inject members on its supertype(s).
   *
   * <p>Note that there is no verification that the type being injected does not have {@link Inject}
   * members, so care should be taken to ensure appropriate use.
   */
  @SuppressWarnings("unchecked")
  public static <T> MembersInjector<T> delegatingTo(MembersInjector<? super T> delegate) {
    return (MembersInjector<T>) delegate;
  }

  private MembersInjectors() {}
}

初始化中調用的noOp方法返回一個NoOpMembersInjector枚舉類,這個類同樣實現了MembersInjector接口,在injectMembers方法中check了instance是否為null。
什么鬼,在注入前不是已經check過了么:

@Override
  public void injectMembers(MainActivity instance) {  
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    supertypeInjector.injectMembers(instance);
    instance.user = userProvider.get();
  }

這個鬼地方先按下不表,因為我也布吉島,回頭再看看回來補上,現在看不懂為什么要連著check兩次。

除了上面這個問題,對于Dagger依賴注入的流程應該是比較清晰的。首先build一個DaggerUserComponent實例,把Module傳進去,再調它的inject方法,DaggerUserComponent的inject方法會調到MainActivityMembersInjector的injectMembers方法,在這里執行真正的注入。

以上是依賴注入一個實例時Dagger生成的輔助代碼。如果我們給兩個成員注入,如下:

public class MainActivity extends AppCompatActivity {

    @Inject
    UserModel user1;

    @Inject
    UserModel user2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerUserComponent.builder()
                .userModule(new UserModule())
                .build()
                .inject(this);

        user2.setName("Arya Stark");
        user2.setAge(12);

        ((TextView) findViewById(R.id.text_view_1)).setText("Name:" + user1.getName() + "::Age:" + user1.getAge());
        ((TextView) findViewById(R.id.text_view_2)).setText("Name:" + user2.getName() + "::Age:" + user2.getAge());
    }
}

就不傳圖了,結果是兩個不一樣的TextView內容,因為這是兩個不同的實例。
那么問題來了,那單例呢?
還是用這個Sample,我給Component類和provide方法都加上 @Singleton 注解,最后的得到的結果就是單例,怎么做到的?
對比了代碼后,我發現加Singleton注解和不加兩種情況下,DaggerUserComponent的初始化代碼偷偷發生了變化。
不加 @Singleton 注解:

private void initialize(final Builder builder) {  
    this.provideUsersProvider = UserModule_ProvideUsersFactory.create(builder.userModule);
    this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
  }

加 @Singleton注解:

private void initialize(final Builder builder) {  
    this.provideUsersProvider = ScopedProvider.create(UserModule_ProvideUsersFactory.create(builder.userModule));
    this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUsersProvider);
  }

看出區別了吧?不加注解的時候拿到的Provider是UserModule_ProvideUsersFactory的實例,加了注解后拿到的是ScopedProvider的實例。
好,來看看這個ScopedProvider.

/**
 * A {@link Provider} implementation that memoizes the result of a {@link Factory} instance.
 *
 * @author Gregory Kick
 * @since 2.0
 */
public final class ScopedProvider<T> implements Provider<T> {
  private static final Object UNINITIALIZED = new Object();

  private final Factory<T> factory;
  private volatile Object instance = UNINITIALIZED;

  private ScopedProvider(Factory<T> factory) {
    assert factory != null;
    this.factory = factory;
  }

  @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;
  }

  /** Returns a new scoped provider for the given factory. */
  public static <T> Provider<T> create(Factory<T> factory) {
    if (factory == null) {
      throw new NullPointerException();
    }
    return new ScopedProvider<T>(factory);
  }
}

其實所謂的ScopedProvider就是把Factory包了一層,在里面存儲了Factory的實例。當我們調用inject時,DaggerUserComponent會把調用轉發給Provider,此時也就是ScopedProvider的get方法,單例的關鍵就在這里。
這個類里定義了一個靜態常量UNINITIALIZED,第一次進入get方法時,會把現在還是靜態常量的instance賦給result局部變量。然后進入判斷,拿鎖,從factory實例中取出UserModel實例,賦給instance和result,然后把result返回。此時,instance變量已經變成了我們之前拿到的那個UserModel實例了。后面再進來,局部變量result(之前的UserModel實例)和靜態常量不等,就再也進不去判斷,直接返回instance,也就實現了單例。
但是注意,這個單例是存在于DaggerUserComponent的實例中的,也就是說,如果DaggerUserComponent產生了新的實例,那么也會產生新的UserModel實例。不能光說不練,來做個實驗。
對MainActivity做以下更改:

public class MainActivity extends AppCompatActivity {

    @Inject
    UserModel user1;

    @Inject
    UserModel user2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DaggerUserComponent.builder()
                .userModule(new UserModule())
                .build()
                .inject(this);

        user2.setName("Arya Stark");
        user2.setAge(12);

        ((TextView) findViewById(R.id.text_view_1)).setText("Name:" + user1.getName() + "::Age:" + user1.getAge());
        ((TextView) findViewById(R.id.text_view_2)).setText("Name:" + user2.getName() + "::Age:" + user2.getAge());

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                DaggerUserComponent.builder()
                        .userModule(new UserModule())
                        .build()
                        .inject(MainActivity.this);
                ((TextView) findViewById(R.id.text_view_1)).setText("Name:" + user1.getName() + "::Age:" + user1.getAge());
                ((TextView) findViewById(R.id.text_view_2)).setText("Name:" + user2.getName() + "::Age:" + user2.getAge());
            }
        }, 2000);
    }
}

在第一次設置TextView的文字完了兩秒后,重新進行一次注入,再更新TextView的顯示。現象就是,先顯示Arya Stark的信息,兩秒后更新為十八歲的lala。因為第二次注入時生成了DaggerUserComponent的新實例,單例也就失效了。

自定義 @UserScope 注解
既然前面已經把Dagger中的 @Singleton 的實現扒了個精光,那么應該很容易自定義Scope了。因為單例存在于ScopedProvider,而ScopedProvider是在Component中創建的,所以要自定義Scope,其實就是控制好Dagger給咱們生成的Component實現的生命周期。
哦對了,先想想Scope是干啥的。我的理解是,保證某個類在一個時期中的實例的單一,也就是在定義的時期中是單例。比如我希望我們的CP項目Model在項目Activity中是單例,那么就可以定義一個ActivityScope,我希望我們的UserModel在用戶登陸后直到登出前是一個單例,那么就定義一個從登陸到登出的UserScope。
現在拓展一下我們的Sample. 在MainActivity之外,再創建SecondActivity和ThirdActivity,假設咱們的用戶在SecondActivity登錄,我們需要UserModel在SecondActivity到ThirdActivity之間是單例。
OK,既然UserScope跨Activity,那只能在比Activity更大的Scope下定義了,這個Scope只能是整個App的ApplicationScope。
好吧,咱們還是按流程來。先為整個App定義最大的Component:

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {

    UserComponent plus(UserModule userModule);

}

注解里標識的AppModule:

@Module
public class AppModule {

    private Application application;

    public AppModule(Application application) {
        this.application = application;
    }

    @Provides
    public Application provideApplication() {
        return application;
    }

}

然后添加兩個Activity,SecondActivity和ThirdActivity,并為他們分別添加Component和Module,代碼就不貼了。
這里咱們要用到一個叫做@Subcomponent的注解,它標識子Component在父Component下進行實現,后面看了源碼就明白了,先記著。

@Subcomponent(modules = {SecondActivityModule.class})
public interface SecondActivityComponent {
    SecondActivity inject(SecondActivity secondActivity);
}
@Subcomponent(modules = {ThirdActivityModule.class})
public interface ThirdActivityComponent {
    ThirdActivity inject(ThirdActivity thirdActivity);
}

這兩個子Component的接口在inject方法中接收一個自己的Activity,然后返回去。
之后,添加一個Application的子類:

public class DaggerDemoApplication extends Application {

    private AppComponent appComponent;
    private UserComponent userComponent;

    public static DaggerDemoApplication get(Context context) {
        return (DaggerDemoApplication) context.getApplicationContext();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        initAppComponent();
    }

    private void initAppComponent() {
        appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this))
                .build();
    }

    public UserComponent createUserComponent() {
        userComponent = appComponent.plus(new UserModule());
        return userComponent;
    }

    public void destroyUserComponent() {
        userComponent = null;
    }

    public AppComponent getAppComponent() {
        return appComponent;
    }

    public UserComponent getUserComponent() {
        return userComponent;
    }
}

注意,要在Manifest里頭為Application標簽加上name屬性,name設為這個類名。這樣,這個類就會在整個App啟動的時候率先執行。
就像前面說的,因為UserScope跨Activity,所以要把它存在AppScope里頭,也就是說當UserScope開始時創建UserComponent的實現并存起來,當UserScope結束的時候,把UserComponent的實例釋放。所以在這里有create和destroy兩個方法,用于控制UserComponent的生命周期。
創建UserScope注解:

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface UserScope {
}

現在更改一下Activity的內容,把MainActivity的內容更換成一個按鈕,用于開啟SecondActivity,在SecondActivity上添加兩個TextView和一個按鈕用于開啟ThirdActivity,ThirdActivity只有兩個TextView。
MainActivity:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(MainActivity.this, SecondActivity.class));
            }
        });
    }
}
public class SecondActivity extends AppCompatActivity {

    @Inject
    UserModel user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        DaggerDemoApplication.get(this).createUserComponent();

        DaggerDemoApplication.get(this)
                .getUserComponent()
                .plus(new SecondActivityModule())
                .inject(this);

        user.setName("Arya");
        user.setAge(12);
        ((TextView) findViewById(R.id.text_view)).setText("Name:" + user.getName() + ":::Age:" + user.getAge());

        findViewById(R.id.button_second).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(SecondActivity.this, ThirdActivity.class));
            }
        });
    }

    @Override
    public void finish() {
        DaggerDemoApplication.get(this).destroyUserComponent();
        super.finish();
    }
}
public class ThirdActivity extends AppCompatActivity {

    @Inject
    UserModel user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);

        DaggerDemoApplication.get(this)
                .getUserComponent()
                .plus(new ThirdActivityModule())
                .inject(this);

        ((TextView) findViewById(R.id.text_view)).setText("Name:" + user.getName() + ":::Age:" + user.getAge());
    }
}

運行一下。


Screenshot_2017-02-09-09-48-06.png

Screenshot_2017-02-09-09-48-10.png

Screenshot_2017-02-09-09-48-14.png

可以看到,我在SecondActivity和ThirdActivity分別進行了一次注入,只在SecondActivity更改了user的值,結果在ThirdActivity中也生效了,說明這個UserModel實例在SecondActivity和ThirdActivity之間是單例的存在。
下面咱來看看Dagger為咱們生成的代碼是怎么做到的。

與之前不同,Dagger在這里并沒有生成UserComponent實現的單獨類,而是將它作為DaggerAppComponent的內部類。

@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerAppComponent implements AppComponent {
  private DaggerAppComponent(Builder builder) {  
    assert builder != null;
  }

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

  @Override
  public UserComponent plus(UserModule userModule) {  
    return new UserComponentImpl(userModule);
  }

  public static final class Builder {
    private AppModule appModule;
  
    private Builder() {  
    }
  
    public AppComponent build() {  
      if (appModule == null) {
        throw new IllegalStateException("appModule must be set");
      }
      return new DaggerAppComponent(this);
    }
  
    public Builder appModule(AppModule appModule) {  
      if (appModule == null) {
        throw new NullPointerException("appModule");
      }
      this.appModule = appModule;
      return this;
    }
  }

  private final class UserComponentImpl implements UserComponent {
    private final UserModule userModule;
    private Provider<UserModel> provideUsersProvider;
  
    private UserComponentImpl(UserModule userModule) {  
      if (userModule == null) {
        throw new NullPointerException();
      }
      this.userModule = userModule;
      initialize();
    }
  
    private void initialize() {  
      this.provideUsersProvider = ScopedProvider.create(UserModule_ProvideUsersFactory.create(userModule));
    }
  
    @Override
    public SecondActivityComponent plus(SecondActivityModule secondActivityModule) {  
      return new SecondActivityComponentImpl(secondActivityModule);
    }
  
    @Override
    public ThirdActivityComponent plus(ThirdActivityModule thirdActivityModule) {  
      return new ThirdActivityComponentImpl(thirdActivityModule);
    }
  
    private final class SecondActivityComponentImpl implements SecondActivityComponent {
      private final SecondActivityModule secondActivityModule;
      private MembersInjector<SecondActivity> secondActivityMembersInjector;
    
      private SecondActivityComponentImpl(SecondActivityModule secondActivityModule) {  
        if (secondActivityModule == null) {
          throw new NullPointerException();
        }
        this.secondActivityModule = secondActivityModule;
        initialize();
      }
    
      private void initialize() {  
        this.secondActivityMembersInjector = SecondActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), UserComponentImpl.this.provideUsersProvider);
      }
    
      @Override
      public SecondActivity inject(SecondActivity secondActivity) {  
        secondActivityMembersInjector.injectMembers(secondActivity);
        return secondActivity;
      }
    }
  
    private final class ThirdActivityComponentImpl implements ThirdActivityComponent {
      private final ThirdActivityModule thirdActivityModule;
      private MembersInjector<ThirdActivity> thirdActivityMembersInjector;
    
      private ThirdActivityComponentImpl(ThirdActivityModule thirdActivityModule) {  
        if (thirdActivityModule == null) {
          throw new NullPointerException();
        }
        this.thirdActivityModule = thirdActivityModule;
        initialize();
      }
    
      private void initialize() {  
        this.thirdActivityMembersInjector = ThirdActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), UserComponentImpl.this.provideUsersProvider);
      }
    
      @Override
      public ThirdActivity inject(ThirdActivity thirdActivity) {  
        thirdActivityMembersInjector.injectMembers(thirdActivity);
        return thirdActivity;
      }
    }
  }
}

這個類相對比較長,但是也不難理解。可以看一眼我們是如何在DaggerDemoApplication中創建AppComponent和UserComponent的實現的。

private void initAppComponent() {
        appComponent = DaggerAppComponent.builder()
                .appModule(new AppModule(this))
                .build();
    }

    public UserComponent createUserComponent() {
        userComponent = appComponent.plus(new UserModule());
        return userComponent;
    }

父Component AppComponent實現的創建與之前無異,使用它的Builder,傳一個AppModule實例再build。而作為子Component的UserComponent的創建就不同了。這里調用AppComponent的plus方法,這個方法是我們定義的接口,接收一個UserModule實例,返回UserComponent.
在我們調用plus的時候,創建了UserComponentImpl實例并返回。在這個內部類中也有兩個我們定義的接口方法,分別接收自己Activity的Module,然后返回自己Activity的Component,在這里又分別創建了SecondActivityComponentImpl和ThirdActivityComponentImpl實例。
再進到這兩個內部類中可以看到,真正的注入方法在這里。

@Override
      public SecondActivity inject(SecondActivity secondActivity) {  
        secondActivityMembersInjector.injectMembers(secondActivity);
        return secondActivity;
      }

注意,這里的secondActivityMembersInjector在SecondActivityComponentImpl的初始化方法中創建:

private void initialize() {  
        this.secondActivityMembersInjector = SecondActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), UserComponentImpl.this.provideUsersProvider);
      } 

而provider是在UserComponentImpl中的初始化方法中創建的:

private void initialize() {  
      this.provideUsersProvider = ScopedProvider.create(UserModule_ProvideUsersFactory.create(userModule));
    }

剩下的注入流程和之前的就一樣了。inject方法中調用SecondActivity_MembersInjector的injectMembers方法,在這里通過調用Provider的get方法,由provider決定是否需要新建實例,需要時再調到咱們的provide方法拿到真正的實例并返回,不需要時直接返回。
以上是對使用 @SubComponent 注解實現自定義Scope的源碼解析。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容