美文网首页
Dagger2进阶-@Qualifier、@Lazy

Dagger2进阶-@Qualifier、@Lazy

作者: dasan沈扬 | 来源:发表于2020-06-27 03:07 被阅读0次

    Qualifier

    当同一个对象有多种注入方式,Dagger2怎么知道使用哪种方式注入呢?
    因此需要用到@Qualifier表识的注解来限定,而@Name也是一种@Qualifier注解。因此提供的地方使用@Name方式如下:

    @Module
    public class SubModule {
    
        @Named("aaa")
        @ActivitySingleton
        @Provides
        public Logger providerLogger(Retrofit retrofit) {
            System.out.println("aaaa");
            return new Logger(retrofit);
        }
    
        @Named("bbb")
        @ActivitySingleton
        @Provides
        public Logger providerLoggerB(Retrofit retrofit) {
            System.out.println("bbbb");
            return new Logger(retrofit);
        }
    
    }
    

    使用不同的方式注入的代码如下:

        @Inject
        @Named("aaa")
        Logger logger;
        @Inject
        @Named("bbb")
        Logger logger2;
    

    在使用@Named("")的地方也可以换成自定义Qualifier注解
    例如

    @Qualifier
    @Documented
    @Retention(RUNTIME)
    public @interface AAAA {
    
    }
    //BBB省略...
    

    则Module中代码如下:

    @Module
    public class SubModule {
    
        @AAA
        @ActivitySingleton
        @Provides
        public Logger providerLogger(Retrofit retrofit) {
            System.out.println("aaaa");
            return new Logger(retrofit);
        }
    
        @BBB
        @ActivitySingleton
        @Provides
        public Logger providerLoggerB(Retrofit retrofit) {
            System.out.println("bbbb");
            return new Logger(retrofit);
        }
    
    }
    

    使用的地方注解也修改成@AAA、@BBB即可。

    Lazy

    Dagger2可以使用懒加载,当Lazy<T> 等同于注入T,只是生成T的时间在调用lazy.get()时,且多次调用get方法,返回的是同一个对象T。例如延时获取Logger的代码如下:

    public class Street {
    
        @Inject
        @AAA
        Logger logger;
        @Inject
        @BBB
        Lazy<Logger> logger2;
    
        public Street() {
    
        }
    
        public void byCoffee() {
            AppComponent netComponent = AppManager.getAppComponent();
            CoffeeShopComponent coffeeShopComponent = netComponent.getCoffeeShopComponentBuilder().build();
            coffeeShopComponent.inject(this);
            logger.log("inject success");
            logger2.get().log("inject success 2");
        }
    
    }
    

    lazy是一种对注入对象的包装,还有一种对注入对象的包装是Provider<T>,看一下CoffeeShopComponent的实现,可以发现里面就用到了Provider<T>,代码如下

    private final class CoffeeShopComponentImpl implements CoffeeShopComponent {
        private Provider<Logger> providerLoggerProvider;
    
        private Provider<Logger> providerLoggerBProvider;
    
        private CoffeeShopComponentImpl(SubModule subModuleParam) {
    
          initialize(subModuleParam);
        }
    
        @SuppressWarnings("unchecked")
        private void initialize(final SubModule subModuleParam) {
          this.providerLoggerProvider = DoubleCheck.provider(SubModule_ProviderLoggerFactory.create(subModuleParam, DaggerAppComponent.this.providerRetrofitProvider));
          this.providerLoggerBProvider = DoubleCheck.provider(SubModule_ProviderLoggerBFactory.create(subModuleParam, DaggerAppComponent.this.providerRetrofitProvider));
        }
    
        @Override
        public void inject(Street street) {
          injectStreet(street);}
    
        private Street injectStreet(Street instance) {
          Street_MembersInjector.injectLogger(instance, providerLoggerProvider.get());
          Street_MembersInjector.injectLogger2(instance, DoubleCheck.lazy(providerLoggerBProvider));
          return instance;
        }
      }
    

    Provider<T>.get() 方法会强制调用生成T,具体如何生成有Module中定义决定。多次调用等同于定义了多个注入对象,因此多次调用是否会返回相同的对象,等同于多个变量是否是相等的,也就是取决于该注入对象是否在Component实例内是单例的。Provider<T>使用方式如下:

    public class Street {
    
        @Inject
        @AAA
        Logger logger;
        @Inject
        @BBB
        Provider<Logger> logger2;
    
        public Street() {
    
        }
    
        public void byCoffee() {
            AppComponent netComponent = AppManager.getAppComponent();
            CoffeeShopComponent coffeeShopComponent = netComponent.getCoffeeShopComponentBuilder().build();
            coffeeShopComponent.inject(this);
            logger.log("inject success,get1:"+logger2.get().hashCode()+" ge2:"+logger2.get().hashCode());
        }
    
    }
    

    logger2.get()多次调用是否返回同一对象取决于Module中限定@BBB的提供方式是否是单例的。
    单例:

        @BBB
        @ActivitySingleton
        @Provides
        public Logger providerLoggerB(Retrofit retrofit) {
            System.out.println("bbbb");
            return new Logger(retrofit);
        }
    

    非单例:

        @BBB
        //@ActivitySingleton
        @Provides
        public Logger providerLoggerB(Retrofit retrofit) {
            System.out.println("bbbb");
            return new Logger(retrofit);
        }
    

    相关文章

      网友评论

          本文标题:Dagger2进阶-@Qualifier、@Lazy

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