關于Guice的單例,自己一直都不是很明白,雖然其使用者文檔也看過幾遍了,可能是本人太愚昧的緣故,一直很迷惑。今天又花了點時間試了一下,基本明白是怎麼會事了。
要保證注入的執行個體是同一個對象,那麼第二次注入時就不能再調用構造器了。
實作的方式用幾種:
也可以直接在ServiceImp上加@Singleton注解,如果是通過@Provides産生的對象,則可以
用把@Provides @Singleton一起放在其方法上。
文檔上說得很清楚:
In linked bindings, scopes apply to the binding source, not the binding target. Suppose we have a class Applebees that implements both Bar and Grill interfaces. These bindings allow for two instances of that type, one for Bars and another for Grills:
bind(Bar.class).to(Applebees.class).in(Singleton.class);
bind(Grill.class).to(Applebees.class).in(Singleton.class);
This is because the scopes apply to the bound type (Bar, Grill), not the type that satisfies that binding (Applebees). To allow only a single instance to be created, use a @Singleton annotation on the declaration for that class. Or add another binding:
bind(Applebees.class).in(Singleton.class);
意思是說提供執行個體的依據是根據其接口而定的,而不是通過其實作類來定的。
如果要讓實作了Bar、Grill的Applebees隻提供一個執行個體(上述情況),可以通過
@Singleton或
bind(Applebees.class).in(Singleton.class);
來實作。
實作好以後,就可以通過多次注入來檢驗是否第二次的注入不再調用其構造方法:
ServiceImp類的預設構造器:
public ServiceImp() {
System.out.println("ServiceImp=============");
}
測試類代碼:
Injector injector = Guice.createInjector(new ServiceModel());
injector.injectMembers(this);
injector.injectMembers(this);
經過測試發現第二次注入并沒有再調用其構造方法。