Как правильно выбрать сферу применения бобов?
Я заметил, что существуют разные области применения бобов:
@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped
Какова цель каждого? Как выбрать правильную область применения для моего боба?
2 ответа
Вступление
Он представляет область действия (время жизни) компонента. Это легче понять, если вы знакомы с работой "под прикрытием" основного веб-приложения с сервлетами: как работают сервлеты? Создание экземпляров, сессий, общих переменных и многопоточности.
@Request/View/Flow/Session/ApplicationScoped
@RequestScoped
bean живет столько же, сколько один HTTP-запрос-ответ (обратите внимание, что Ajax-запрос также считается одним HTTP-запросом). @ViewScoped
bean живет до тех пор, пока вы взаимодействуете с тем же представлением JSF с помощью обратных передач, которые вызывают методы действия, возвращающие null
/ void
без какой-либо навигации / перенаправления. @FlowScoped
bean живет до тех пор, пока вы перемещаетесь по указанной коллекции представлений, зарегистрированных в файле конфигурации потока. @SessionScoped
Бин живет до тех пор, пока установлен HTTP-сеанс. @ApplicationScoped
Бин живет до тех пор, пока работает веб-приложение. Обратите внимание, что CDI @Model
в основном стереотип для @Named @RequestScoped
, так же правила применяются.
Выбор области действия зависит исключительно от данных (состояния), которые содержит и представляет компонент. использование @RequestScoped
для простых и не AJAX форм / презентаций. использование @ViewScoped
для расширенных динамических представлений с поддержкой ajax (проверка на основе ajax, рендеринг, диалоги и т. д.). использование @FlowScoped
для "мастера" ("вопросника") шаблон сбора входных данных, распределенных по нескольким страницам. использование @SessionScoped
для специфических данных клиента, таких как зарегистрированный пользователь и пользовательские настройки (язык и т. д.). использование @ApplicationScoped
для данных / констант всего приложения, таких как выпадающие списки, которые одинаковы для всех, или управляемые компоненты без каких-либо переменных экземпляра и имеющие только методы.
Злоупотребляя @ApplicationScoped
Компонент bean для данных в области сеанса / просмотра / запроса сделает его доступным для всех пользователей, поэтому любой может увидеть данные друг друга, что просто неверно. Злоупотребляя @SessionScoped
Компонент bean для данных области просмотра / запроса сделает его доступным для всех вкладок / окон в одном сеансе браузера, поэтому конечный пользователь может испытывать неудобства при взаимодействии с каждым представлением после переключения между вкладками, что плохо для пользовательского опыта. Злоупотребляя @RequestScoped
Компонент bean for view scoped data может привести к повторной инициализации данных вида view по умолчанию при каждой обратной передаче (ajax), что может привести к нерабочим формам ( см. также пункты 4 и 5 здесь). Злоупотребляя @ViewScoped
боб для запроса, данных сессии или приложения и злоупотребления @SessionScoped
bean-компонент для данных области приложения не влияет на клиента, но он излишне занимает память сервера и является совершенно неэффективным.
Обратите внимание, что область видимости не должна выбираться исходя из факторов, влияющих на производительность, за исключением случаев, когда у вас действительно мало места в памяти и вы хотите полностью отказаться от состояния; вам нужно использовать исключительно @RequestScoped
bean и fiddle с параметрами запроса для поддержания состояния клиента. Также обратите внимание, что если у вас есть одна страница JSF с данными различной области действия, то вполне допустимо поместить их в отдельные компоненты поддержки в области, соответствующей области данных. Бобы могут просто получить доступ друг к другу через @ManagedProperty
в случае JSF управляемых бобов или @Inject
в случае CDI управляемых бобов.
Смотрите также:
- Разница между областью просмотра и запроса в управляемых компонентах
- Преимущества использования JSF Faces Flow вместо обычной навигационной системы
- Коммуникация в JSF2 - управляемые бобовые области
@CustomScoped/NoneScoped/Dependent
Это не упоминается в вашем вопросе, но (устаревшая) JSF также поддерживает @CustomScoped
а также @NoneScoped
, которые редко используются в реальном мире. @CustomScoped
должен ссылаться на обычай Map<K, Bean>
реализация в какой-то более широкой области, которая переопределена Map#put()
и / или Map#get()
чтобы иметь более точный контроль над созданием и / или уничтожением бобов.
JSF @NoneScoped
и CDI @Dependent
в основном живет так же долго, как одиночная EL-оценка на бобе. Представьте себе форму входа в систему с двумя полями ввода, относящимися к свойству bean-компонента, и командную кнопку, указывающую на действие bean-компонента, то есть, в общей сложности, с тремя выражениями EL, тогда фактически будут созданы три экземпляра. Один с установленным именем пользователя, один с установленным паролем и один, для которого вызывается действие. Обычно вы хотите использовать эту область только для bean-компонентов, которые должны существовать столько, сколько bean-компонент, в который он вводится. Так что если @NoneScoped
или же @Dependent
вводится в @SessionScoped
то будет жить до тех пор, пока @SessionScoped
боб.
Смотрите также:
- Истек срок действия конкретного экземпляра управляемого компонента через интервал времени
- что такое безобъектный боб и когда его использовать?
- Какова область управляемых компонентов по умолчанию в приложении JSF 2?
Флеш прицел
Как и в прошлом, JSF также поддерживает флеш-прицел. Он поддерживается недолговечным cookie-файлом, который связан с записью данных в области сеанса. Перед перенаправлением в ответе HTTP будет установлен cookie со значением, которое однозначно связано с вводом данных в область сеанса. После перенаправления будет проверено наличие файла cookie области флеш-памяти, а запись данных, связанная с файлом cookie, будет удалена из области сеанса и помещена в область запроса перенаправленного запроса. Наконец, cookie будет удален из ответа HTTP. Таким образом, перенаправленный запрос имеет доступ к запрашиваемым данным, которые были подготовлены в начальном запросе.
На самом деле это недоступно как управляемый компонент, то есть не существует такой вещи, как @FlashScoped
, Вспышка доступна только как карта через ExternalContext#getFlash()
в управляемых бобах и #{flash}
в EL.
Смотрите также:
Начиная с JSF 2.x существует 4 области применения бобов:
- @SessionScoped
- @RequestScoped
- @ApplicationScoped
- @ViewScoped
Область действия сеанса: область действия сеанса сохраняется с момента установления сеанса до его завершения. Сеанс завершается, если веб-приложение вызывает метод invalidate для объекта HttpSession или по истечении времени ожидания.
RequestScope: объем запроса является недолгим. Он начинается при отправке HTTP-запроса и заканчивается после отправки ответа клиенту. Если вы помещаете управляемый компонент в область запроса, новый экземпляр создается с каждым запросом. Стоит рассмотреть объем запроса, если вас беспокоит стоимость хранения области сеанса.
ApplicationScope: область действия приложения сохраняется в течение всего срока действия веб-приложения. Эта область является общей для всех запросов и всех сеансов. Вы помещаете управляемые bean-компоненты в область приложения, если один bean-компонент должен совместно использоваться всеми экземплярами веб-приложения. Бин создается, когда его сначала запрашивает любой пользователь приложения, и он остается активным до тех пор, пока веб-приложение не будет удалено с сервера приложений.
ViewScope: область просмотра была добавлена в JSF 2.0. Область видимости компонента сохраняется, пока отображается та же страница JSF. (Спецификация JSF использует термин представление для страницы JSF.) Как только пользователь переходит на другую страницу, бин выходит из области видимости.
Выберите объем, который вы основали на вашем требовании.
Источник: Core Java Server Faces, 3-е издание, Дэвид Гири и Кей Хорстманн [Страница №. 51 - 54]