У меня проблемы с пониманием того, как работают синглтон-инстанции Guice. Я прочитал доступную документацию (здесь - http://code.google.com/p/google-guice/wiki/Scopes), но я все еще не могу понять некоторые вещи:
1) Я интегрировал Guice с Tomcat и настроил некоторые привязки в модуле ServletModule:
bind(MyServlet.class).asEagerSingleton();
serve("myUrl").with(MyServlet.class);
serve("myOtherUrl").with(MyOtherServlet.class);
(где класс MyOtherServlet имеет аннотацию @Singleton над ним)
Мое намерение здесь состояло в том, чтобы иметь два сервлета, один из которых активно создается, а другой нет. Однако кажется, что строка "serve ... with ..." автоматически создает экземпляры объектов сервлетов, даже если этот класс не связан как активный одиночный объект.
Ссылка, которую я прикрепил выше, упоминает различие между Guice, работающим в Stage.Development и Stage.Production - однако это все же происходило, даже когда я явно использовал Stage.Development (который по умолчанию в любом случае).
Есть ли способ избежать этого?
2) (продолжение 1) Пытаясь убедиться, что MyServlet сначала создается, хотя все сервлеты создаются с нетерпением, я изменил порядок модулей (и операторов связывания) при создании Injector, так что появляется привязка для MyServlet первый. Однако я обнаружил, что он все еще создается позже, чем некоторые другие привязки (классов не сервлетов), которые имели вид:
bind(MyInterface.class).to(MyClass.class).asEagerSingleton()
, хотя эти другие привязки появились позже в порядке модулей / привязок.
Я изучил его и обнаружил, что Guice просто создает экземпляры нетерпеливых синглетонов, которые были связаны формой «bind ... to ... asEagerSingleton ()», прежде чем он выполняет один из «bind ... asEagerSingleton ()», и поэтому я решил это, изменив строку:
связывания (MyServlet.class) .asEagerSingleton ();
в:
связывания (MyServletDummyInterface.class) .то (MyServlet.class) .asEagerSingleton ()
и это действительно сработало. Тем не менее, я бы предпочел не использовать фиктивный интерфейс только для решения этой проблемы, поэтому мне было интересно, есть ли у кого-нибудь лучшее решение для этого ..?
3) У меня есть два модуля Guice - один ServletModule и один AbstractModule.
ServletModule configureServlets () имеет следующую привязку:
serve("aUrl").with(SomeServlet.class);
Настройка абстрактного модуля () имеет следующие привязки:
bind(SomeImpl.class).asEagerSingleton();
bind(SomeInterface.class).to(SomeImpl.class).in(Singleton.class);
Кроме того, класс SomeServlet имеет внедренное поле типа SomeInterface и имеет аннотацию @Singleton поверх класса.
Теперь можно ожидать, что при создании инжектора будет создан экземпляр класса SomeImpl, и тот же экземпляр будет внедрен в экземпляр SomeServlet. Как упоминалось ранее, сервлеты, ограниченные выражением «serve ... with ...», также, похоже, стремительно создаются, но в любом случае должен быть только один экземпляр SomeImpl. И все же по какой-то причине я получил два экземпляра SomeImpl, созданных при этом.
Чтобы обойти это, я немного смешал две строки в configure (), и вместо вышеупомянутых у меня были следующие строки:
bind(SomeImpl.class).in(Singleton.class)
bind(SomeInterface.class).to(SomeImpl.class).asEagerSingleton();
и затем все заработало, и я получил только один экземпляр SomeImpl. Я не совсем понимаю, почему переключение должно иметь значение - я вижу, как последний способ «лучше», но я ожидаю, что оба будут работать правильно, поэтому мне просто интересно, если я здесь что-то не так делаю ..
Извините за длину,
Спасибо за помощь!