美文网首页
再探Dagger2

再探Dagger2

作者: 一个大西瓜CPI | 来源:发表于2018-06-09 18:41 被阅读9次

    先看Dagger2的注解


    image

    1.Inject注解

    • 作用在构造方法上
    //空参构造
    public class PersonBean {
    
        String name;
    
        @Inject
        public PersonBean() {
        }
    
    }
    
    //生成的工厂类
    public final class PersonBean_Factory implements Factory<PersonBean> {
      private static final PersonBean_Factory INSTANCE = new PersonBean_Factory();
    
      @Override
      public PersonBean get() {
        return new PersonBean();
      }
    
      public static Factory<PersonBean> create() {
        return INSTANCE;
      }
    }
    //有参构造
    public class PersonBean {
    
        String name;
    
        @Inject
        public PersonBean(String name) {
            this.name = name;
        }
    }
    
    生成的工厂类
    public final class PersonBean_Factory implements Factory<PersonBean> {
      private final Provider<String> nameProvider;
    
      public PersonBean_Factory(Provider<String> nameProvider) {
        assert nameProvider != null;
        this.nameProvider = nameProvider;
      }
    
      @Override
      public PersonBean get() {
        return new PersonBean(nameProvider.get());
      }
    
      public static Factory<PersonBean> create(Provider<String> nameProvider) {
        return new PersonBean_Factory(nameProvider);
      }
    }
    
    
    • 作用在字段上
    // 在person类中注入变量
    public class Clothes {
    
        String color;
    
        @Inject
        public Clothes(String color) {
            this.color = color;
        }
    }
    
    public class PersonBean {
    
        String name;
        @Inject
        Clothes clothes;
    
        @Inject
        public PersonBean(String name) {
            this.name = name;
        }
    }
    

    此时在apt目录下多生成了一个PersonBean_MembersInjector文件,如图:


    dagger_1.PNG
    public final class PersonBean_MembersInjector implements MembersInjector<PersonBean> {
      private final Provider<Clothes> clothesProvider;
    
      public PersonBean_MembersInjector(Provider<Clothes> clothesProvider) {
        assert clothesProvider != null;
        this.clothesProvider = clothesProvider;
      }
    
      public static MembersInjector<PersonBean> create(Provider<Clothes> clothesProvider) {
        return new PersonBean_MembersInjector(clothesProvider);
      }
    
      @Override
      public void injectMembers(PersonBean instance) {
        if (instance == null) {
          throw new NullPointerException("Cannot inject members into a null reference");
        }
        instance.clothes = clothesProvider.get();
      }
    
      public static void injectClothes(PersonBean instance, Provider<Clothes> clothesProvider) {
        instance.clothes = clothesProvider.get();
      }
    }
    

    apt插件为PersonBean生成了一个成员注入类,该类提供了PersonBean需要的Clothes实例。PersonBean_Factory也改变成了如下结构:

    public final class PersonBean_Factory implements Factory<PersonBean> {
      private final MembersInjector<PersonBean> personBeanMembersInjector;
    
      private final Provider<String> nameProvider;
    
      public PersonBean_Factory(
          MembersInjector<PersonBean> personBeanMembersInjector, Provider<String> nameProvider) {
        assert personBeanMembersInjector != null;
        this.personBeanMembersInjector = personBeanMembersInjector;
        assert nameProvider != null;
        this.nameProvider = nameProvider;
      }
    
      @Override
      public PersonBean get() {
        return MembersInjectors.injectMembers(
            personBeanMembersInjector, new PersonBean(nameProvider.get()));
      }
    
      public static Factory<PersonBean> create(
          MembersInjector<PersonBean> personBeanMembersInjector, Provider<String> nameProvider) {
        return new PersonBean_Factory(personBeanMembersInjector, nameProvider);
      }
    }
    
    

    2.Component注解

    @Component
    public interface DemoComponent {
    
        Student student();
    }
    
    

    apt会为该注解生成一个工厂类:

    public final class DaggerDemoComponent implements DemoComponent {
      private DaggerDemoComponent(Builder builder) {
        assert builder != null;
      }
    
      public static Builder builder() {
        return new Builder();
      }
    
      public static DemoComponent create() {
        return new Builder().build();
      }
    
      @Override
      public Student student() {
        return new Student();
      }
    
      public static final class Builder {
        private Builder() {}
    
        public DemoComponent build() {
          return new DaggerDemoComponent(this);
        }
      }
    }
    

    在Component里面添加的抽象方法,会在对应的DaggerDemoComponent类中进行实现。

    3.Provider注解和Module注解

    @Module
    public class OneModule {
    
        @Provides
        public Clothes provideClothes() {
            return new Clothes("紫色");
        }
    
        @Provides
        public PersonBean providePersonBean() {
            return new PersonBean("大西瓜");
        }
    
    }
    

    会生成模块名+方法名+Factory的工程类(OneModule_ProvidePersonBeanFactory)。
    注意:
    1.模块必须要使用Module注解修饰。
    2.Module中的方法需要provider开头,否则生成的文件会报错。

    public final class OneModule_ProvidePersonBeanFactory implements Factory<PersonBean> {
      private final OneModule module;
    
      public OneModule_ProvidePersonBeanFactory(OneModule module) {
        assert module != null;
        this.module = module;
      }
    
      @Override
      public PersonBean get() {
        return Preconditions.checkNotNull(
            module.providePersonBean(), "Cannot return null from a non-@Nullable @Provides method");
      }
    
      public static Factory<PersonBean> create(OneModule module) {
        return new OneModule_ProvidePersonBeanFactory(module);
      }
    }
    
    public final class OneModule_ProvideClothesFactory implements Factory<Clothes> {
      private final OneModule module;
    
      public OneModule_ProvideClothesFactory(OneModule module) {
        assert module != null;
        this.module = module;
      }
    
      @Override
      public Clothes get() {
        return Preconditions.checkNotNull(
            module.provideClothes(), "Cannot return null from a non-@Nullable @Provides method");
      }
    
      public static Factory<Clothes> create(OneModule module) {
        return new OneModule_ProvideClothesFactory(module);
      }
    }
    
    

    4.Singleton注解

    @Singleton
    @Component(modules = {OneModule.class})
    public interface DemoComponent {
    
        void inject(MainActivity activity);
    
        Student student();
    }
    

    为Component提供Singleton注解,在apt生成的代码中,会进行DoubleCheck的检查,保证单例。

      private void initialize(final Builder builder) {
    
        this.provideXiguaPersonBeanProvider =
            DoubleCheck.provider(OneModule_ProvideXiguaPersonBeanFactory.create(builder.oneModule));
    
        this.mainActivityMembersInjector =
            MainActivity_MembersInjector.create(provideXiguaPersonBeanProvider);
    
        this.studentProvider = DoubleCheck.provider(Student_Factory.create());
      }
    

    二、让组件(Component)依赖Module

    @Component(modules = {OneModule.class})
    public interface DemoComponent {
    
        Student student();
    }
    

    在DaggerDemoComponent中的Buider对象中生成oneModule(OneModule oneModule)方法。

    public final class DaggerDemoComponent implements DemoComponent {
      private DaggerDemoComponent(Builder builder) {
        assert builder != null;
      }
    
      public static Builder builder() {
        return new Builder();
      }
    
      public static DemoComponent create() {
        return new Builder().build();
      }
    
      @Override
      public Student student() {
        return new Student();
      }
    
      public static final class Builder {
        private Builder() {}
    
        public DemoComponent build() {
          return new DaggerDemoComponent(this);
        }
    
        /**
         * @deprecated This module is declared, but an instance is not used in the component. This
         *     method is a no-op. For more, see https://google.github.io/dagger/unused-modules.
         */
        @Deprecated
        public Builder oneModule(OneModule oneModule) {
          Preconditions.checkNotNull(oneModule);
          return this;
        }
      }
    }
    

    在Activity中注入对象

    public class MainActivity extends AppCompatActivity {
    
        @Inject
        PersonBean personBean;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            DaggerDemoComponent.builder()
                    .oneModule(new OneModule())
                    .build()
                    .inject(this);
        }
    }
    

    注意:需要使用inject方法注入指定类。
    在加入inject方法后,生成了如下方法。
    1.在DaggerDemoComponent中找到所有@Inject修饰的需要注入的变量的provider,并且在build后对这些变量进行赋值。
    2.在inject(this)的时候,会将已经赋值的变量找到
    MainActivity_MembersInjector(注入类+MembersInjector)中真正的变量进行赋值。

    public final class DaggerDemoComponent implements DemoComponent {
      private Provider<PersonBean> providePersonBeanProvider;
    
      private MembersInjector<MainActivity> mainActivityMembersInjector;
    
      private DaggerDemoComponent(Builder builder) {
        assert builder != null;
        initialize(builder);
      }
    
      public static Builder builder() {
        return new Builder();
      }
    
      public static DemoComponent create() {
        return new Builder().build();
      }
    
      @SuppressWarnings("unchecked")
      private void initialize(final Builder builder) {
    
        this.providePersonBeanProvider = OneModule_ProvidePersonBeanFactory.create(builder.oneModule);
    
        this.mainActivityMembersInjector =
            MainActivity_MembersInjector.create(providePersonBeanProvider);
      }
    
      @Override
      public void inject(MainActivity activity) {
        mainActivityMembersInjector.injectMembers(activity);
      }
    
      @Override
      public Student student() {
        return new Student();
      }
    
      public static final class Builder {
        private OneModule oneModule;
    
        private Builder() {}
    
        public DemoComponent build() {
          if (oneModule == null) {
            this.oneModule = new OneModule();
          }
          return new DaggerDemoComponent(this);
        }
    
        public Builder oneModule(OneModule oneModule) {
          this.oneModule = Preconditions.checkNotNull(oneModule);
          return this;
        }
      }
    }
    
    public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
      private final Provider<PersonBean> personBeanProvider;
    
      public MainActivity_MembersInjector(Provider<PersonBean> personBeanProvider) {
        assert personBeanProvider != null;
        this.personBeanProvider = personBeanProvider;
      }
    
      public static MembersInjector<MainActivity> create(Provider<PersonBean> personBeanProvider) {
        return new MainActivity_MembersInjector(personBeanProvider);
      }
    
      @Override
      public void injectMembers(MainActivity instance) {
        if (instance == null) {
          throw new NullPointerException("Cannot inject members into a null reference");
        }
        instance.personBean = personBeanProvider.get();
      }
    
      public static void injectPersonBean(
          MainActivity instance, Provider<PersonBean> personBeanProvider) {
        instance.personBean = personBeanProvider.get();
      }
    }
    
    

    三、其他的一些问题

    1. @Inject 和 @Provides 的优先级
      Dagger2 依赖查找的顺序是先查找 Module 内所有的 @Provides 提供的依赖,如果查找不到再去查找 @Inject 提供的依赖。

    相关文章

      网友评论

          本文标题:再探Dagger2

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