Пользовательские пружинные прицелы?

Кто-нибудь знает какие-либо другие специальные пружинные прицелы, кроме Область контекста сервлета и ThreadScope?

Если вы сделали какую-то кастомную область с закрытым исходным кодом, мне также было бы интересно узнать, что она делает и как это сработало для вас. (Я мог бы предположить, что кто-то сделает WindowScope в настольном приложении?)

Я открыт для всех вариантов использования, я хочу расширить свой кругозор здесь.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
11
0
9 943
9

Ответы 9

Мы реализовали нашу собственную специальную область действия Spring. Большая часть нашего кода работает на относительно низком уровне, близко к базе данных, и мы поддерживаем концептуальный уровень поверх этого с собственной объектной моделью источников данных, ссылок, атрибутов и т. д.

В любом случае, многим bean-компонентам требуется так называемый StorageDictionary (инкапсуляция этого графа объектов) для выполнения своей работы. Когда мы вносим нетривиальные изменения в граф объекта, словарь иногда нужно удалить и воссоздать заново. Следовательно, мы реализовали настраиваемую область для объектов, которые были словарь с ограниченным объемом, и часть признания недействительности данного словаря включает в себя очистку этой настраиваемой области. Это позволяет Spring обрабатывать удобную форму автоматического кэширования этих объектов. Вы получаете один и тот же объект каждый раз, пока словарь не станет недействительным, после чего вы получите новый объект.

Это помогает не только обеспечить согласованность, но также позволяет самим объектам кэшировать ссылки на сущности в словаре, безопасно зная, что кеш будет действителен до тех пор, пока они сами могут быть извлечены Spring. Это, в свою очередь, позволяет нам создавать их как неизменяемые объекты (при условии, что они могут быть связаны с помощью внедрения конструктора), что в любом случае очень полезно делать везде, где это возможно.

Этот метод не будет работать везде и сильно зависит от характеристик программного обеспечения (например, если бы словарь регулярно изменялся, это было бы ужасно неэффективно, а если бы он никогда не обновлялся, это было бы ненужным и немного менее эффективным, чем прямой доступ). Однако это определенно помогло нам передать управление жизненным циклом Spring концептуально простым и, на мой взгляд, довольно элегантным способом.

Действительно здорово, ты расширил мой кругозор там. Я вижу "кешированную" область видимости или что-то подобное. Вероятно, также хорошо для вычисленных производных данных, которые, похоже, вы делаете.

krosenvold 16.01.2009 20:52

В моей компании мы создали две настраиваемые области: одна будет использовать поток или запрос, а другая будет использовать поток или сеанс. Идея состоит в том, что для bean-компонентов с ограниченной областью видимости можно использовать одну область без изменения конфигурации в зависимости от среды выполнения (JUnit или контейнер сервлета). Это также очень удобно, когда вы запускаете элементы в Quartz и больше не имеете доступной области запроса или сеанса.

Мы решили это, используя вместо этого фиктивные объекты сеанса / запроса в контексте JUnit, поэтому у нас есть доступная область запроса / сеанса. Будут ли эти два решения функционально эквивалентны? (Возможно, тоже можно использовать в кварцевом прицеле ...)

krosenvold 16.01.2009 20:54

Что касается различий между JUnit и контекстом сервлета, я определенно думаю, что они эквивалентны. Для Quartz, я думаю, все немного сложнее. Если вы внедряете компоненты с ограниченной областью видимости в свои службы и пытаетесь вызвать эти службы из задания Quartz, это будет сложно обойти.

cliff.meyers 16.01.2009 20:59

У меня нет опыта работы с кварцем, но работает ли он в одном потоке или в разных потоках?

krosenvold 16.01.2009 21:38

Чтобы быть точным, у нас есть собственный ContextLoader, который регистрирует запрос областей и сеанс для модульных тестов. Реализации этих прицелов основаны на весенних версиях этих прицелов. Нельзя ли использовать этот подход для кварца?

krosenvold 16.01.2009 22:07

Oracle Coherence реализовал область данных для Spring beans. Подвести итог:

A Data Grid Bean is a proxy to a java.io.Serializable Bean instance that is stored in a non-expiring Coherence Distributed Cache (called near-datagridbeans).

Сам никогда ими не пользовался, но кажутся классными.

Задний план:

Я работаю над одним веб-приложением, которое запускает 4 разных веб-сайта в одном контексте сервлета. У каждого сайта есть собственное доменное имя, например www.examplesite1.com, www.examplesite2.com и т. д.

Проблема:

Сайтам иногда требуется собственный настроенный экземпляр компонента из контекста приложения (обычно для настраиваемого отображения сообщений или форматирования объектов).

Например, предположим, что сайты 1 и 2 используют bean-компонент «standardDateFormatter», сайт 3 использует bean-компонент «usDateFormatter», а сайт 4 использует bean-компонент «ukDateFormatter».

Решение:

Я планирую использовать объем "сайта".

У нас есть такое перечисление Site:

enum Site {
    SITE1, SITE2, SITE3, SITE4;
}

Затем у нас есть фильтр, который сохраняет одно из этих значений Site в потоке запроса с помощью ThreadLocal. Это "идентификатор разговора" области сайта.

Тогда в контексте приложения будет bean-компонент с именем «dateFormatter» с 'scope = "site"'. Затем, где бы мы ни хотели использовать средство форматирования даты, будет использоваться правильный формат для текущего сайта пользователя.

Добавлено позже:

Пример кода здесь:

http://github.com/eliotsykes/spring-site-scope

Apache Orchestra предоставляет SpringConversationScope.

Область действия языкового стандарта Spring на основе языкового стандарта пользователя в веб-приложении.

См. соответствующая вики-страница

В моей компании мы также реализовали пружинный пользовательский прицел. У нас есть мультитенантная система, где каждый клиент может настраивать параметры. Наша область действия, основанная на Пример, кэширует bean-компоненты, которые зависят от клиента. Таким образом, каждый раз, когда пользователь клиента входит в систему, эти параметры кэшируются и повторно используются, когда другие пользователи тех же клиентов входят в систему.

В приложении Spring Batch мы реализовали предметная область.

Задний план

У нас есть множество компонентов @Service, которые что-то вычисляют на основе текущего элемента пакета. Многим из них нужен одинаковый рабочий процесс:

  1. Определите соответствующие части предмета.
  2. Инициализировать материал на основе элемента.
  3. Для каждой части элемента вычислите что-нибудь (используя материал).

Мы переместили рабочий процесс в метод шаблона базового класса, поэтому подклассы реализуют только findItemParts(Item) (выполнение 1 и 2) и computeSomething(ItemPart) (выполнение 3). Таким образом, они стали с сохранением состояния (материал, инициализированный в findItemParts, необходим в computeSomething), и это состояние должно быть очищено перед следующим элементом.

Некоторые из этих сервисов также включают внедренные bean-компоненты Spring, которые также являются производными от текущего элемента и должны быть впоследствии удалены.

Дизайн

Мы реализовали AbstractScopeRegisteringItemProcessor, который регистрирует элемент и позволяет подклассам регистрировать производные bean-компоненты. В конце своего метода process он удаляет элемент из контекста своей области и производные bean-компоненты с помощью DefaultSingletonBeanRegistry.destroySingleton.

Как это получилось

Он работает, но имеет следующие проблемы:

  1. Очистить производные бины без регистрации (только на основе их @Scope) не удалось. Конкретный обработчик должен их создать и зарегистрировать.
  2. AbstractScopeRegisteringItemProcessor было бы лучше использовать композицию и динамически реализовывать все интерфейсы базового процессора. Но тогда полученный bean-компонент @StepScope является прокси для объявленный возвращаемый тип (то есть AbstractScopeRegisteringItemProcessor или ItemProcessor) без требуемых интерфейсов обратного вызова.

РЕДАКТИРОВАТЬ

С помощью решение @Eliot Sykes и общего кода плюс Регистрация BeanDefinition @ Cheetah я смог избавиться от регистрации как singleton beans. Вместо этого ItemScopeContext (хранилище, используемое как процессором, так и реализацией Scope; настраивается на Java с помощью статического метода @Bean) реализует BeanDefinitionRegistryPostProcessor. Он регистрирует FactoryBean, чей getObject() возвращает текущий элемент, или выдает исключение, если его нет. Теперь @Component, помеченный @Scope(scopeName = "Item", proxyMode = ScopedProxyMode.TARGET_CLASS), может просто ввести элемент, и его не нужно регистрировать для очистки в конце области.

Так что, в конце концов, все получилось.

Однажды я использовал своего рода диапазон разговора для хранения некоторых объектов в области сеанса, чтобы сохранить их при повторном входе на ту же страницу, но ограничился одной страницей, чтобы не оставлять бесполезные объекты в сеансе. Реализация просто сохраняла URL-адрес страницы и очищала диапазон разговора при каждом изменении страницы.

Другие вопросы по теме