如果我尝试构造一个新的单例实例,Guice 是否可能抛出异常?
例如:
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(MySingleton.class).in(Singleton.class);
}
}
@Singleton
public class MySingleton {
MySingleton() { /* ... */ }
}
public class RightWay {
public void withInjector() {
Injector injector = Guice.createInjector(new MyModule());
MySingleton mySingleton = injector.getInstance(MySingleton.class);
}
}
public class AnotherRightWay {
private final MySingleton mySingleton;
@Inject
public AnotherRightWay(MySingleton mySingleton) {
this.mySingleton = mySingleton;
}
}
public class TheWrongWay {
public void directInstantiation() {
MySingleton mySingleton = new MySingleton(); // I want an exception here!
}
}
通过将 MySingleton
的构造函数包设为私有(private),我可以限制错误的范围,但是当然,同一个包中的类仍然可以将 Spanner 投入工作。这里的优势是我对 AnotherRightWay
的单元测试可以轻松地将 MySingleton
的模拟传递给它的构造函数。
或者,我可以使 MySingleton
的构造函数受到保护,Guice 可以处理它,并且我仍然可以通过让我的模拟扩展 MySingleton
来模拟。但是 MySingleton
用户可以在不知道危险的情况下做同样的事情。
如果 Guice 可以抛出异常,我可以在我的单元测试中使用反射来构建模拟,但我的用户不会轻易地意外创建 MySingleton
的非单例版本。
这可能吗?我应该只使用 package-private 还是 protected 并学会喜欢炸弹?
最佳答案
Guice 不是魔法。你不能强制它在 Injector
之外做一些事情,所以不,你不能那样做,事实上你不应该这样做。
正如您已经注意到的那样,最好的方法是使 MySingleton
的构造函数成为包私有(private)的。这样,除了 Guice 之外,包外的任何人都无法构建它。由于此包由您控制,因此可以安全地假设没有人会通过 Guice(当然是使用您的模块)以外的其他方式创建 MySingleton
。
这不是“炸弹”。包私有(private)修饰符正是用于此目的。假定 您 控制您的包,因此可以将构造函数和其他东西设为包私有(private)并假定除了您之外没有人会调用它们。
关于java - Guice 可以断言单例不是直接实例化的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22605169/