Guice - Как поделиться одним экземпляром Singleton через несколько инжекторов / модулей - PullRequest
16 голосов
/ 02 декабря 2011

Как правило, область действия @Singleton не относится к шаблону Singleton.

Согласно книге «Инъекция зависимости» «Дханджи»:

Очень просто, контекст синглтона - это сам инжектор. Жизнь синглтон привязан к сроку службы инжектора (как на рисунке 5.8). Таким образом, только один экземпляр одиночного инжектор. Важно подчеркнуть этот последний момент, так как это возможно наличие нескольких форсунок в одном приложении. В По такому сценарию каждый инжектор будет содержать отдельный экземпляр объект одной области действия.

Singleton scope

Можно ли совместно использовать один и тот же экземпляр Singleton через несколько модулей и несколько инжекторов?

Ответы [ 2 ]

24 голосов
/ 03 декабря 2011

Вы можете использовать Injector.createChildInjector :

// bind shared singletons here
Injector parent = Guice.createInjector(new MySharedSingletonsModule());
// create new injectors that share singletons
Injector i1 = parent.createChildInjector(new MyModule1(), new MyModule2());
Injector i2 = parent.createChildInjector(new MyModule3(), new MyModule4());
// now injectors i1 and i2 share all the bindings of parent
3 голосов
/ 02 декабря 2011

Я не понимаю, зачем вам это нужно, но если вы действительно хотите, это возможно:

package stackoverflow;

import javax.inject.Inject;
import javax.inject.Singleton;

import junit.framework.Assert;

import org.junit.Test;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;

public class InjectorSingletonTest {

    static class ModuleOne extends AbstractModule {
        @Override
        protected void configure() {
            bind(MySingleton.class);
        }
    }

    static class ModuleTwo extends AbstractModule {
        final MySingleton singleton;

        @Inject
        ModuleTwo(MySingleton singleton){
            this.singleton = singleton;
        }

        @Override
        protected void configure() {
            bind(MySingleton.class).toInstance(singleton);
        }
    }

    @Singleton
    static class MySingleton { }

    @Test
    public void test(){
        Injector injectorOne = Guice.createInjector(new ModuleOne());

        Module moduleTwo = injectorOne.getInstance(ModuleTwo.class);
        Injector injectorTwo = Guice.createInjector(moduleTwo);

        MySingleton singletonFromInjectorOne =
                injectorOne.getInstance(MySingleton.class);

        MySingleton singletonFromInjectorTwo =
                injectorTwo.getInstance(MySingleton.class);

        Assert.assertSame(singletonFromInjectorOne, singletonFromInjectorTwo);
    }
}
...