美文网首页
Dagger2 生成代码学习笔记

Dagger2 生成代码学习笔记

作者: 乌龟爱吃肉 | 来源:发表于2017-02-08 14:56 被阅读0次

    上一篇记录了如何使用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的源码解析。

    相关文章

      网友评论

          本文标题:Dagger2 生成代码学习笔记

          本文链接:https://www.haomeiwen.com/subject/lzuvittx.html