java Dagger 2单例不工作
使用Dagger2,我试图在一个范围内的多个位置注入一个单例对象。然而,我的解决方案似乎每次都会创建一个新实例
在这个测试项目中,我有一个初始化DaggerModule的MainActivity。DaggerModule提供对象Box和Cat,Box将Cat作为参数。在我的主要活动中,我也养猫。最后,我检查了注入的两个Cat变量的引用(分别在框中和MainActivity中),但它们不是同一个实例
如果我在MainActivity中调用provideCat()两次,则会提供相同的实例
主要活动:
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerModule daggerModule = new DaggerModule();
DaggerComponent daggerComponent = Dagger_DaggerComponent.builder()
.daggerModule(daggerModule).build();
// Same Cat instance returned.
Cat cat1 = daggerComponent.provideCat();
Cat cat2 = daggerComponent.provideCat();
Log.d("=== cat1: ", cat1.toString());
Log.d("=== cat2: ", cat2.toString());
// Different Cat instance returned. Why?
Box box = daggerComponent.provideBox();
Log.d("=== box cat: ", box.getCat().toString());
}
}
@Module
public class DaggerModule {
@Provides
@Singleton
public Cat provideCat() {
return new Cat();
}
@Provides
@Singleton
public Box provideBox() {
return new Box(provideCat());
}
}
@Singleton
@Component(modules = { DaggerModule.class })
public interface DaggerComponent {
Cat provideCat();
Box provideBox();
}
public class Cat {
@Inject
public Cat() {
}
}
public class Box {
private Cat mCat;
@Inject
public Box(Cat cat) {
mCat = cat;
}
public Cat getCat() {
return mCat;
}
}
提前谢谢
编辑: 如果provideBox接受Cat参数并使用该参数来创建框,而不是直接从provideBox中调用provideCat,则该方法有效
// Doesn't work, new Cat instance created.
@Provides
@Singleton
public Box provideBox() {
return new Box(provideCat());
}
vs
// Works, same singleton injected.
@Provides
@Singleton
public Box provideBox(Cat cat) {
return new Box(cat);
}
在main活动中调用provideCat与在DaggerModule中从provideBox中调用有什么区别?可能是Dagger编译器处理DaggerModule的方式与处理外部类的方式不同,并且如果我在其中调用provideCat,则不会应用注释吗
# 1 楼答案
我想从provideBox内部调用provideCat的原因是我对组件接口的误解。我误解了组件接口实际上不是由模块实现的,因此模块方法的参数不必在组件的相应方法中声明。如果是这样的话,它会迫使我在MainActivity的provideBox方法调用中创建Cat实例,这是我想要避免的(因此直接在模块的provideBox方法中调用provideCat)。事实上,在组件方法中声明参数甚至使Dagger编译器无法编译
但由于组件方法不接受参数,解决方案只是在需要时将实例作为参数注入模块方法中(而不是从模块本身中调用相应的提供方法),并且只需要从MainActivity调用组件的无参数方法,如下所示:
主要活动:
组成部分:
模块:
MainActivity和Box的Cat单例实例现在是相同的,我不必从MainActivity中声明它们,但Dagger处理了所有这些。成功不过,仍然不确定为什么从外部类调用提供方法时,其工作方式与从模块本身内部调用不同