“一盘沙拉”带你入门Dagger2(四)之 @Singleton

系列文章

“一盘沙拉”带你入门Dagger2(一)之HelloWorld

“一盘沙拉”带你入门Dagger2(二)之带参数怎么办

“一盘沙拉”带你入门Dagger2(三)之@Qualifier

“一盘沙拉”带你入门Dagger2(四)之 @Singleton

“一盘沙拉”带你入门Dagger2(五)之 @Scope

@Singleton可以方便地实现单例(全局单例)

我们在Salad类里面引入两个Orange的实例,查看他们的内存地址

public class Salad {

   @Inject//桔子1
    Orange orange1;

   @Inject//桔子2
    Orange orange2;

 ...
    public Salad() {
      ...

        Log.e("TAG", "orange1内存地址:"+orange1.toString());
        Log.e("TAG", "orange2内存地址:"+orange2.toString());

    }

  ...
}

打印log:发现两个对象是两个内存地址,说明目前Orange不是单例

E/TAG: orange1内存地址:com.demo.dagger2demo2.Orange@16e3e55f
E/TAG: orange2内存地址:com.demo.dagger2demo2.Orange@3565cbac

下面我们使用@Singleton让Orange类实现单例

  1. 在SaladModule里,在provideOrange方法前添加 @Singleton 即可

    @Module
        public class SaladModule {
           ...
    
    
            @Singleton // 单例,注意是在方法上添加,不是在类上面
            @Provides
            public Orange provideOrange(Knife knife) {
                return new Orange(knife);
            }
    
            ...
    
        }
    
  2. 在SaladComponent里,在接口上添加@Singleton 注释 即可

    @Singleton //注意是在接口上添加,注意位置
    @Component(modules = {SaladModule.class})//指明要在那些Module里寻找依赖
        public interface SaladComponent {
        ...
        //不是在这里添加@Singleton
        Orange provideOragne();
    
        void inject(Salad salad);
    
    }
  3. Salad类不变,还是引入了两个Orange对象,打印log,发现两个对象的内存地址是一样的,证明此时Orange是单例
E/TAG: orange1内存地址:com.demo.dagger2demo2.Orange@16e3e55f
E/TAG: orange2内存地址:com.demo.dagger2demo2.Orange@16e3e55f

总结:

一个简单地注解,方便地实现了单例。
这个@Singleton 是java提供给我们的注解,其实在Dagger2里面有一个注解@Scope也是用来实现单例的(这个说法不严谨)

java提供的@Singleton 只能实现全局单例,即只要在这个app里,无论在哪里,这个类都是单例,
而Dagger2提供的@Scope,能够让一个类在某个区域内实现单例,脱离这个区域他又不是单例了。

比如:Knife小刀,我们让Knife在注入到苹果、桔子时是单例(即苹果、桔子用的是同一把刀),Knife在注入Meat(肉)这个类里时,是另一把刀(很显然,切肉和切水果不能使用同一把刀),这是如果使用@Singleton 是不行的,他使得Knife在全局都是单例(即切水果和切肉都是用同一把刀),但是使用@Scope可以实现这个需求。

Scope就是区域、范围的意思,他会让Dagger2知道,在那些范围内使用的是一个依赖的同一个对象,而不仅仅是在全局指定单例模式

下一篇,说说@Scope

你可能感兴趣的:(Dagger2)