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




Мы реализовали нашу собственную специальную область действия Spring. Большая часть нашего кода работает на относительно низком уровне, близко к базе данных, и мы поддерживаем концептуальный уровень поверх этого с собственной объектной моделью источников данных, ссылок, атрибутов и т. д.
В любом случае, многим bean-компонентам требуется так называемый StorageDictionary (инкапсуляция этого графа объектов) для выполнения своей работы. Когда мы вносим нетривиальные изменения в граф объекта, словарь иногда нужно удалить и воссоздать заново. Следовательно, мы реализовали настраиваемую область для объектов, которые были словарь с ограниченным объемом, и часть признания недействительности данного словаря включает в себя очистку этой настраиваемой области. Это позволяет Spring обрабатывать удобную форму автоматического кэширования этих объектов. Вы получаете один и тот же объект каждый раз, пока словарь не станет недействительным, после чего вы получите новый объект.
Это помогает не только обеспечить согласованность, но также позволяет самим объектам кэшировать ссылки на сущности в словаре, безопасно зная, что кеш будет действителен до тех пор, пока они сами могут быть извлечены Spring. Это, в свою очередь, позволяет нам создавать их как неизменяемые объекты (при условии, что они могут быть связаны с помощью внедрения конструктора), что в любом случае очень полезно делать везде, где это возможно.
Этот метод не будет работать везде и сильно зависит от характеристик программного обеспечения (например, если бы словарь регулярно изменялся, это было бы ужасно неэффективно, а если бы он никогда не обновлялся, это было бы ненужным и немного менее эффективным, чем прямой доступ). Однако это определенно помогло нам передать управление жизненным циклом Spring концептуально простым и, на мой взгляд, довольно элегантным способом.
В моей компании мы создали две настраиваемые области: одна будет использовать поток или запрос, а другая будет использовать поток или сеанс. Идея состоит в том, что для bean-компонентов с ограниченной областью видимости можно использовать одну область без изменения конфигурации в зависимости от среды выполнения (JUnit или контейнер сервлета). Это также очень удобно, когда вы запускаете элементы в Quartz и больше не имеете доступной области запроса или сеанса.
Мы решили это, используя вместо этого фиктивные объекты сеанса / запроса в контексте JUnit, поэтому у нас есть доступная область запроса / сеанса. Будут ли эти два решения функционально эквивалентны? (Возможно, тоже можно использовать в кварцевом прицеле ...)
Что касается различий между JUnit и контекстом сервлета, я определенно думаю, что они эквивалентны. Для Quartz, я думаю, все немного сложнее. Если вы внедряете компоненты с ограниченной областью видимости в свои службы и пытаетесь вызвать эти службы из задания Quartz, это будет сложно обойти.
У меня нет опыта работы с кварцем, но работает ли он в одном потоке или в разных потоках?
Чтобы быть точным, у нас есть собственный ContextLoader, который регистрирует запрос областей и сеанс для модульных тестов. Реализации этих прицелов основаны на весенних версиях этих прицелов. Нельзя ли использовать этот подход для кварца?
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"'. Затем, где бы мы ни хотели использовать средство форматирования даты, будет использоваться правильный формат для текущего сайта пользователя.
Добавлено позже:
Пример кода здесь:
Apache Orchestra предоставляет SpringConversationScope.
Область действия языкового стандарта Spring на основе языкового стандарта пользователя в веб-приложении.
В моей компании мы также реализовали пружинный пользовательский прицел. У нас есть мультитенантная система, где каждый клиент может настраивать параметры. Наша область действия, основанная на Пример, кэширует bean-компоненты, которые зависят от клиента. Таким образом, каждый раз, когда пользователь клиента входит в систему, эти параметры кэшируются и повторно используются, когда другие пользователи тех же клиентов входят в систему.
В приложении Spring Batch мы реализовали предметная область.
У нас есть множество компонентов @Service, которые что-то вычисляют на основе текущего элемента пакета. Многим из них нужен одинаковый рабочий процесс:
Мы переместили рабочий процесс в метод шаблона базового класса, поэтому подклассы реализуют только findItemParts(Item) (выполнение 1 и 2) и computeSomething(ItemPart) (выполнение 3). Таким образом, они стали с сохранением состояния (материал, инициализированный в findItemParts, необходим в computeSomething), и это состояние должно быть очищено перед следующим элементом.
Некоторые из этих сервисов также включают внедренные bean-компоненты Spring, которые также являются производными от текущего элемента и должны быть впоследствии удалены.
Мы реализовали AbstractScopeRegisteringItemProcessor, который регистрирует элемент и позволяет подклассам регистрировать производные bean-компоненты. В конце своего метода process он удаляет элемент из контекста своей области и производные bean-компоненты с помощью DefaultSingletonBeanRegistry.destroySingleton.
Он работает, но имеет следующие проблемы:
@Scope) не удалось. Конкретный обработчик должен их создать и зарегистрировать.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-адрес страницы и очищала диапазон разговора при каждом изменении страницы.
Действительно здорово, ты расширил мой кругозор там. Я вижу "кешированную" область видимости или что-то подобное. Вероятно, также хорошо для вычисленных производных данных, которые, похоже, вы делаете.