简体   繁体   English

创建不绑定到注入器的Guice单例

[英]Creating Guice singleton that's not tied to an Injector

Our project is setup as follows: 我们的项目设置如下:

1) Main module: Contains a driver program which starts a Spark streaming server. 1)主模块:包含启动Spark流服务器的驱动程序。 It has its own Guice injector. 它具有自己的Guice注射器。

2) When message comes in, it goes to another module, which creates it's own Guice injector. 2)当消息进入时,它转到另一个模块,该模块创建它自己的Guice注射器。

3) This module uses classes in other modules which themselves use dependent modules. 3)此模块使用其他模块中的类,而其他模块本身也使用相关模块。 Each of these modules creates its own Guice injector so that it can work independently, tested individually etc. 这些模块中的每一个都创建自己的Guice注射器,因此可以独立工作,单独测试等。

Here's a problem: Now we need a Singleton, but an object created as @Singleton is bound to an injector (Not to a ClassLoader), so when the Injector goes away the object goes away. 这是一个问题:现在我们需要一个Singleton,但是将创建为@Singleton的对象绑定到注入器(而不是ClassLoader),因此当Injector消失时,该对象也会消失。

Questions: 问题:

1) Is our architecture bad? 1)我们的架构不好吗? Should we not be creating an injector in every module? 我们不应该在每个模块中都创建一个注射器吗?

2) How do we create a Singleton that will remain in a ClassLoader even when injector goes away? 2)我们如何创建即使注入器消失也仍保留在ClassLoader中的Singleton?

BTW, we use Netflix Governator on top on Guice. 顺便说一句,我们在Guice顶部使用Netflix Governor。

Note: Answer for the question which is supposedly duplicate of this question doesn't answer how a 'single' injector created on the top level module can be passed to the sub-modules. 注意:对这个问题的回答(可能是该问题的重复)不能回答如何将在顶层模块上创建的“单个”注入器传递给子模块。 Also, if the sub-modules themselves don't have an injector, can we write standalone unit tests for them? 另外,如果子模块本身没有注入器,我们可以为它们编写独立的单元测试吗?

An idea for question 2 would be to use a provider that you can bind in all your different Modules. 问题2的想法是使用可以绑定到所有不同模块中的提供程序。 This provider would access a singleton that that exists 'outside' of Guice. 该提供者将访问位于Guice外部的单例。

I have crafted a simple example where I provide access to a static field. 我制作了一个简单的示例,其中提供了对静态字段的访问。 You can change that to use the implementation of the Singleton pattern that suits your needs. 您可以更改它以使用适合您需求的Singleton模式的实现。

public class SingletonProvider implements Provider<TheSingleton> {

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

Then we bind this to our different modules 然后将其绑定到我们的不同模块

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);
    }
}

And then I create two different injectors that return this same instance 然后创建两个不同的注射器,它们返回相同的实例

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);


    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM