Как создать нестандартную область видимости Guice без потоков? - PullRequest
4 голосов
/ 23 марта 2010

Кажется, что все готовые реализации Scope от Guice изначально основаны на потоках (или полностью игнорируют потоки):

Scopes.SINGLETON и Scopes.NO_SCOPE игнорируют потоки и являются крайними случаями: глобальная область и без области.

ServletScopes.REQUEST и ServletScopes.SESSION в конечном итоге зависят от извлечения объектов с областью действия из ThreadLocal<Context>. Полученный Context содержит ссылку на HttpServletRequest, которая содержит ссылку на объекты области действия, хранящиеся как именованные атрибуты (где имя происходит от com.google.inject.Key).

Класс SimpleScope из пользовательской области Вики Guice также предоставляют реализацию для каждого потока, используя переменную-член ThreadLocal<Map<Key<?>, Object>>.

С этой преамбулой мой вопрос заключается в следующем: как можно создать область, не основанную на потоках? Кажется, что-то, что я могу использовать для поиска Map<Key<?>, Object>, отсутствует, так как единственные вещи, переданные в Scope.scope(), это Key<T> и Provider<T>.

Заранее спасибо за ваше время.

1 Ответ

7 голосов
/ 28 апреля 2011

Немного неясно, что вы хотите - вам не нужны области, основанные на потоках, и вам не нужны области, которые игнорируют потоки.

Но да, области видимости предназначены для управления жизненным циклом объекта и определения момента повторного использования экземпляра. Поэтому на самом деле вы спрашиваете: «Каковы другие возможности повторного использования экземпляра, кроме« всегда использовать один и тот же экземпляр »,« никогда не использовать один и тот же экземпляр »и« использовать экземпляр в зависимости от среды выполнения текущего потока » ? "

Вот что приходит на ум:

  • Используйте один и тот же экземпляр в течение фиксированного периода времени. Примером здесь может быть файл конфигурации, который перезагружается и обрабатывается каждые десять минут.
  • Выполните некоторый сетевой вызов, чтобы узнать, следует ли повторно использовать данный объект (возможно, это быстрый вызов, чтобы определить, нужно ли восстанавливать объект, но вызов для восстановления объекта медленный)
  • Повторно использовать тот же объект, пока не поступит какой-то внешний вызов, говорящий нам о перезагрузке
  • Повторно использовать один и тот же объект для каждого потока, но не с областью, которая явно введена и оставлена ​​как области сервлета. (Таким образом, один экземпляр на поток)
  • Область действия "этот поток и дочерние потоки", основанная на InheritableThreadLocal, а не на простом ThreadLocal.
  • В связи с этим, Scope и ExecutorService на основе пула потоков, которые работают совместно, чтобы экземпляры распределялись между потоком и заданиями, которые он отправляет для фонового выполнения.
  • Вытащить экземпляры из пула; это сложно, так как нам нужен хороший способ вернуть объекты в пул после завершения. (Возможно, вы могли бы объединить эту идею с чем-то вроде области действия запроса, чтобы объекты могли быть возвращены в пул после завершения запроса)
  • Область действия, в которую входят две или более других областей, поэтому, например, мы можем получить объект конфигурации, который перечитывается каждые 10 минут, за исключением того, что один и тот же экземпляр используется в течение всего времени существования данного запроса.
...