创建Guice单例,它不与Injector绑定

时间:2015-10-21 00:57:10

标签: java scala dependency-injection guice

我们的项目设置如下:

1)主模块:包含启动Spark流服务器的驱动程序。它有自己的Guice注射器。

2)当消息进入时,它会转到另一个模块,该模块会创建它自己的Guice注入器。

3)此模块使用其他模块中的类,这些模块本身使用依赖模块。这些模块中的每一个都创建了自己的Guice注入器,因此它可以独立工作,单独测试等。

这里有一个问题:现在我们需要一个Singleton,但是创建为@Singleton的对象被绑定到一个注入器(而不是一个ClassLoader),所以当Injector消失时,对象就会消失。

问题:

1)我们的架构不好吗?我们不应该在每个模块中创建一个注射器吗?

2)即使注射器消失,我们如何创建一个将保留在ClassLoader中的Singleton?

顺便说一句,我们在Guice上使用Netflix Governator。

注意:对于这个问题应该重复的问题的答案并没有回答单个'在顶级模块上创建的注入器可以传递给子模块。另外,如果子模块本身没有注入器,我们可以为它们编写独立的单元测试吗?

1 个答案:

答案 0 :(得分:2)

问题2的一个想法是使用可以在所有不同模块中绑定的提供程序。该提供商将访问存在于外部的单身人士。 Guice。

我制作了一个简单的例子,我可以访问静态字段。您可以更改它以使用适合您需要的Singleton模式的实现。

public class SingletonProvider implements Provider<TheSingleton> {

    private static final TheSingleton instance  = new TheSingleton();
    @Override
    public TheSingleton get() {
        return instance;
    }
}

然后我们将它绑定到我们的不同模块

public class Module1 extends AbstractModule {

    @Override
    protected void configure() {
       bind(TheSingleton.class).toProvider( SingletonProvider.class);
    }
}
public class Module2 extends AbstractModule {

    @Override
    protected void configure() {
       bind(TheSingleton.class).toProvider( SingletonProvider.class);
    }
}

然后我创建两个不同的注入器来返回同一个实例

public class Test {
    public static void main(String[] args) {
        Injector injector1 = Guice.createInjector(new Module1());

        TheSingleton instance = injector1.getInstance(TheSingleton.class);
        System.out.println("instance = " + instance);

        Injector injector2 = Guice.createInjector(new Module2());
        TheSingleton instance2 = injector2.getInstance(TheSingleton.class);
        System.out.println("instance2 = " + instance2);


    }
}