您的位置:首页 > 其它

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

2016-09-02 16:42 459 查看

系列文章

“一盘沙拉”带你入门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类实现单例

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

@Module
public class SaladModule {
...

@Singleton // 单例,注意是在方法上添加,不是在类上面
@Provides
public Orange provideOrange(Knife knife) {
return new Orange(knife);
}

...

}


在SaladComponent里,在接口上添加@Singleton 注释 即可

@Singleton //注意是在接口上添加,注意位置
@Component(modules = {SaladModule.class})//指明要在那些Module里寻找依赖
public interface SaladComponent {
...
//不是在这里添加@Singleton
Orange provideOragne();

void inject(Salad salad);

}


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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: