java - Guice 可以断言单例不是直接实例化的吗?

标签 java dependency-injection guice

如果我尝试构造一个新的单例实例,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/

相关文章:

java - CDI 是否为默认生产者提供 API?

java - 'com.mycompany.client.gin.ClientGinjector' 的延迟绑定(bind)失败

java - SOAP 响应在 CXF + 简单前端 + Aegis 数据绑定(bind)中错误地反序列化为 null

java - 如何在 JUnit 测试容器中的 MySQLContainer 中导入 sql 转储文件

java - 如何在 maven-jar-plugin 中指定 --main-class 和 --module-version?

php - Symfony 2 依赖注入(inject)和 Autowiring

java - Spring MVC - @Autowired 是如何工作的?

go - 如何创建线程安全的 rand.Source?

java - 如何使用 Guice 3.0 为 JSP 提供服务?

java - 如何使 JSONObject 的 toString() 将 UTF-8 字符编码为 un​​icode,就像 PHP 的 json_encode 中一样?