美文网首页Android开发Android技术知识Android知识
Dagger2代码分析理解Component和Module

Dagger2代码分析理解Component和Module

作者: wenson123 | 来源:发表于2018-04-13 15:51 被阅读74次

    Dagger2主要有如下几个核心概念:

    @Component

    @Module

    @Inject

    @Singleton

    很多同学在学习Dagger2时都知道如何使用,但可能知其然而不知其所以然,本文以Dagger2官方例子,通过分析生成后代码,帮助大家加深对上述概念的理解:

    coffee.png

    CoffeeShop.java

    @Singleton
    @Component(modules = {DripCoffeeModule .class})
    public interface CoffeeShop {
      void inject(MyApplication application);
    }
    

    DripCoffeeModule.java

    @Module
    public class DripCoffeeModule {
    
      @Provides
      Heater provideHeater() {
        return new ElectricHeater();
      }
    
      @Provides
      Pump providePump(Thermosiphon pump) {
        return pump;
      }
    }
    

    CoffeeShop.java编译生成DaggerCoffeeShop.java,代码比较冗长读者可以不需要细看,主要包含成员变量,initialize方法,Builder类三部分。

    public final class DaggerCoffeeShop implements CoffeeShop {
    
      private MembersInjector<MyApplication> myApplicationMembersInjector;
    
      private Provider<Heater> provideHeaterProvider;
    
      private Provider<Thermosiphon> thermosiphonProvider;
    
      private Provider<Pump> providePumpProvider;
    
      private MembersInjector<CoffeeMaker> coffeeMakerMembersInjector;
    
      private Provider<CoffeeMaker> coffeeMakerProvider;
    
      private DaggerCoffeeShop(Builder builder) {
        assert builder != null;
        initialize(builder);
      }
    
      public static Builder builder() {
        return new Builder();
      }
    
      public static CoffeeShop create() {
        return new Builder().build();
      }
    
      @SuppressWarnings("unchecked")
      private void initialize(final Builder builder) {
    
        this.myApplicationMembersInjector =
            MyApplication_MembersInjector.create(dispatchingAndroidInjectorProvider);
    
        this.provideHeaterProvider =
            DripCoffeeModule_ProvideHeaterFactory.create(builder.dripCoffeeModule);
    
        this.thermosiphonProvider =
            DoubleCheck.provider(Thermosiphon_Factory.create(provideHeaterProvider));
    
        this.providePumpProvider =
            DripCoffeeModule_ProvidePumpFactory.create(builder.dripCoffeeModule, thermosiphonProvider);
    
        this.coffeeMakerMembersInjector =
            CoffeeMaker_MembersInjector.create(provideHeaterProvider, providePumpProvider);
    
        this.coffeeMakerProvider =
            DoubleCheck.provider(
                CoffeeMaker_Factory.create(
                    coffeeMakerMembersInjector, provideHeaterProvider, providePumpProvider));
      }
    
      @Override
      public void inject(MyApplication application) {
        myApplicationMembersInjector.injectMembers(application);
      }
    
      public static final class Builder {
        private DripCoffeeModule dripCoffeeModule;
    
        private Builder() {}
    
        public CoffeeShop build() {
          if (dripCoffeeModule == null) {
            this.dripCoffeeModule = new DripCoffeeModule();
          }
          return new DaggerCoffeeShop(this);
        }
    
        public Builder dripCoffeeModule(DripCoffeeModule dripCoffeeModule) {
          this.dripCoffeeModule = Preconditions.checkNotNull(dripCoffeeModule);
          return this;
        }
      }
    
    
    

    从上述生成的代码看,我们可以知道

    1. Component从module加载生成所有的创建对象的Factory create mehod。
       private Provider<Heater> provideHeaterProvider;  
    
        this.provideHeaterProvider =
            DripCoffeeModule_ProvideHeaterFactory.create(builder.dripCoffeeModule);
    
        this.thermosiphonProvider =
            DoubleCheck.provider(Thermosiphon_Factory.create(provideHeaterProvider));
    

    2.如果标记为@Singleton,则会生成DoubleCheck.provider()保证创建为单例模式

        this.coffeeMakerProvider =
            DoubleCheck.provider(
                CoffeeMaker_Factory.create(
                    coffeeMakerMembersInjector, provideHeaterProvider, providePumpProvider));
    

    3.内部类Builder负责创建component依赖的所有Module

      public static final class Builder {
        private DripCoffeeModule dripCoffeeModule;
    
        private Builder() {}
    
        public CoffeeShop build() {
          if (dripCoffeeModule == null) {
            this.dripCoffeeModule = new DripCoffeeModule();
          }
          return new DaggerCoffeeShop(this);
        }
    
        public Builder dripCoffeeModule(DripCoffeeModule dripCoffeeModule) {
          this.dripCoffeeModule = Preconditions.checkNotNull(dripCoffeeModule);
          return this;
        }
      }
    

    4.如果对构造函数标记为@Inject,则会自动生成MembersInjector类

    CoffeeMaker.java

    @Singleton
    public class CoffeeMaker {
        @Inject Heater heater;
    
        @Inject Pump pump;
    
        @Inject
        public CoffeeMaker(Heater heater, Pump pump) {
            Log.i("wenson", "CoffeeMake create");
            this.heater = heater;
            this.pump = pump;
        }
    
        public void brew(){
    
        }
    }
    

    Component类生成对应的方法,其中包含CoffeeMaker_MembersInjector 和 CoffeeMaker_Factory这2个负责实际创建的类。

      private MembersInjector<CoffeeMaker> coffeeMakerMembersInjector;
    
        this.coffeeMakerMembersInjector =
            CoffeeMaker_MembersInjector.create(provideHeaterProvider, providePumpProvider);
    
        this.coffeeMakerProvider =
            DoubleCheck.provider(
                CoffeeMaker_Factory.create(
                    coffeeMakerMembersInjector, provideHeaterProvider, providePumpProvider));
    

    查看生成的CoffeeMaker_MembersInjector类, 这个类负责对象的具体创建

    public final class CoffeeMaker_MembersInjector implements MembersInjector<CoffeeMaker> {
      private final Provider<Heater> heaterProvider;
    
      private final Provider<Pump> pumpProvider;
    
      public CoffeeMaker_MembersInjector(Provider<Heater> heaterProvider, Provider<Pump> pumpProvider) {
        assert heaterProvider != null;
        this.heaterProvider = heaterProvider;
        assert pumpProvider != null;
        this.pumpProvider = pumpProvider;
      }
    
      public static MembersInjector<CoffeeMaker> create(
          Provider<Heater> heaterProvider, Provider<Pump> pumpProvider) {
        return new CoffeeMaker_MembersInjector(heaterProvider, pumpProvider);
      }
    
      @Override
      public void injectMembers(CoffeeMaker instance) {
        if (instance == null) {
          throw new NullPointerException("Cannot inject members into a null reference");
        }
        instance.heater = heaterProvider.get();
        instance.pump = pumpProvider.get();
      }
    
      public static void injectHeater(CoffeeMaker instance, Provider<Heater> heaterProvider) {
        instance.heater = heaterProvider.get();
      }
    
      public static void injectPump(CoffeeMaker instance, Provider<Pump> pumpProvider) {
        instance.pump = pumpProvider.get();
      }
    }
    

    查看生成的CoffeeMaker_Factory类,主要负责对象创建的再封装

    public final class CoffeeMaker_Factory implements Factory<CoffeeMaker> {
      private final MembersInjector<CoffeeMaker> coffeeMakerMembersInjector;
    
      private final Provider<Heater> heaterProvider;
    
      private final Provider<Pump> pumpProvider;
    
      public CoffeeMaker_Factory(
          MembersInjector<CoffeeMaker> coffeeMakerMembersInjector,
          Provider<Heater> heaterProvider,
          Provider<Pump> pumpProvider) {
        assert coffeeMakerMembersInjector != null;
        this.coffeeMakerMembersInjector = coffeeMakerMembersInjector;
        assert heaterProvider != null;
        this.heaterProvider = heaterProvider;
        assert pumpProvider != null;
        this.pumpProvider = pumpProvider;
      }
    
      @Override
      public CoffeeMaker get() {
        return MembersInjectors.injectMembers(
            coffeeMakerMembersInjector, new CoffeeMaker(heaterProvider.get(), pumpProvider.get()));
      }
    
      public static Factory<CoffeeMaker> create(
          MembersInjector<CoffeeMaker> coffeeMakerMembersInjector,
          Provider<Heater> heaterProvider,
          Provider<Pump> pumpProvider) {
        return new CoffeeMaker_Factory(coffeeMakerMembersInjector, heaterProvider, pumpProvider);
      }
    }
    

    总结:

    • Dagger的优点是是编译期静态生成对象依赖注入的所有代码,不是运行时动态反射方式。

    • 优点是运行时无性能副作用,缺点是编译后生成大量类,对象注入需要指定类,生成对应的类方法。

    • 即使使用google的AndroidInjector, 也只是方便开发人员少写一部分代码。

    从以上代码分析可以帮助我们更深刻得理解Component和Module的概念。

    • 打个比方:Component类似注射器,Module是连接注射器的各个原料工厂。

    • 我们可以定义各种原料工厂(Module), 有网络的NetModule(Retrofit),有存储的DBModule(Room)等等。

    看上述代码很累的同学,建议将Dagger2官方例子导入到工程里实际编译阅读,方便理解。

    相关文章

      网友评论

        本文标题:Dagger2代码分析理解Component和Module

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