Как правильно выбрать сферу применения бобов?


381

Я заметил, что существуют разные области применения бобов, такие как:

@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped

Какова цель каждого? Как выбрать правильную область применения для моего боба?


Ответы:


485

Введение

Он представляет область действия (время жизни) компонента. Это легче понять, если вы знакомы с работой «под прикрытием» основного веб-приложения с сервлетами: как работают сервлеты? Создание экземпляров, сессий, общих переменных и многопоточности .


@Request/View/Flow/Session/ApplicationScoped

@RequestScopedБоб живет до тех пор , как цикл запроса-ответа одного HTTP (обратите внимание , что рассчитывает запрос Ajax как одного запроса HTTP тоже). @ViewScopedБоб живет до тех пор , пока вы взаимодействуя с тем же точкой зрения JSF по постбэк , какие методы действий вызова возвращающихся null/ voidбез навигации / редиректа. @FlowScopedБоб живет до тех пор , пока вы перемещаясь по заданной коллекции представлений , зарегистрированных в файле конфигурации потока. @SessionScopedБоб живет до тех пор, установленной HTTP сессии. @ApplicationScopedБоб живет до тех пор , как бежит веб - приложений. Обратите внимание , что КДИ @Modelв основном стереотип для @Named @RequestScoped, так же правила.

Выбор области действия зависит исключительно от данных (состояния), которые содержит и представляет компонент. Используйте @RequestScopedдля простых и не AJAX форм / презентаций. Используйте @ViewScopedдля расширенных динамических представлений с поддержкой ajax (проверка на основе ajax, рендеринг, диалоги и т. Д.). Используйте @FlowScopedшаблон «мастер» («вопросник») для сбора входных данных, распределенных по нескольким страницам. Используйте @SessionScopedдля клиентских данных, таких как зарегистрированный пользователь и пользовательские настройки (язык и т. Д.). Используйте @ApplicationScopedдля данных / констант всего приложения, таких как выпадающие списки, которые одинаковы для всех, или управляемые компоненты без каких-либо переменных экземпляра и имеющие только методы.

Злоупотребление @ApplicationScopedbean-компонентом для данных в области сеанса / просмотра / запроса сделало бы его доступным для всех пользователей, поэтому любой другой может увидеть данные друг друга, что просто неверно. Злоупотребление @SessionScopedbean-компонентом для данных области просмотра / запроса сделало бы его доступным для всех вкладок / окон в одном сеансе браузера, поэтому конечный пользователь может испытывать неудобства при взаимодействии с каждым представлением после переключения между вкладками, что плохо для пользовательского опыта. Злоупотребление @RequestScopedbean-компонентом для данных в области просмотра приведет к повторной инициализации данных в области представления по умолчанию при каждой обратной передаче (ajax), что может привести к нерабочим формам ( см. Также пункты 4 и 5 здесь ). Злоупотребление @ViewScopedbean-компонентом для запроса, данных сеанса или области приложения и злоупотребление@SessionScoped bean-компонент для данных области приложения не влияет на клиента, но он излишне занимает память сервера и является совершенно неэффективным.

Обратите внимание, что область видимости не должна выбираться исходя из факторов, влияющих на производительность, за исключением случаев, когда у вас действительно мало места в памяти и вы хотите полностью отказаться от состояния; вам нужно было бы использовать исключительно @RequestScopedbean-компоненты и скрипты с параметрами запроса для поддержания состояния клиента. Также обратите внимание, что если у вас есть одна JSF-страница с данными различной области, то вполне допустимо поместить их в отдельные компоненты поддержки в области, соответствующей области данных. Бины могут просто получать доступ друг к другу через @ManagedPropertyJSF-управляемые бины или @InjectCDI-управляемые бины.

Смотрите также:


@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 также поддерживает флеш-область. Он поддерживается недолговечным cookie-файлом, который связан с вводом данных в область сеанса. Перед перенаправлением в ответе HTTP будет установлен cookie со значением, которое однозначно связано с вводом данных в область сеанса. После перенаправления будет проверено наличие файла cookie области флеш-памяти, а запись данных, связанная с файлом cookie, будет удалена из области сеанса и помещена в область запроса перенаправленного запроса. Наконец, cookie будет удален из ответа HTTP. Таким образом, перенаправленный запрос имеет доступ к запрашиваемым данным, которые были подготовлены в начальном запросе.

На самом деле это недоступно как управляемая область действия bean-компонента, то есть такой вещи как @FlashScoped. Область действия Flash доступна только в виде карты через ExternalContext#getFlash()управляемые компоненты и #{flash}EL.

Смотрите также:


4
Я думаю, что ссылка на ваш ответ на вопрос « Как и когда уничтожается компонент области видимости в JSF? » Здесь уместна.
Лий

3
@Cold: это старая область видимости CDI, в JSF 2.2 она заменена на @FlowScoped(нет необходимости вручную запускать / останавливать ее).
BalusC

1
И DeltaSpike дополнительно имеет ViewAccesscopedиWindowScoped
Kukeltje

@BalusC, я думаю, что есть проблема с ViewScopedбином в MyFaces 2.2. В настоящее время я сталкиваюсь с проблемой ViewScopedбина и Ajax, которую я разместил здесь . В MyFaces JIRA также обсуждается эта тема.
Тапас Бозе

CDI определяет четыре встроенные области действия: @RequestScoped @SessionScoped @ApplicationScoped @ConversationScoped почему области, которые вы описываете, отличаются?
Хосейн Агаджани

122

Начиная с JSF 2.3 все области действия bean-компонентов, определенные в package javax.faces.beanpackage, устарели, чтобы выровнять области с CDI. Более того, они применимы, только если ваш компонент использует @ManagedBeanаннотацию. Если вы используете версии JSF ниже 2.3, обратитесь к устаревшему ответу в конце.


Начиная с JSF 2.3, здесь представлены области, которые можно использовать на базовых компонентах JSF:

1.@javax.enterprise.context.ApplicationScoped Область действия приложения сохраняется в течение всего срока действия веб-приложения. Эта область является общей для всех запросов и всех сеансов. Это полезно, когда у вас есть данные для всего приложения.

2@javax.enterprise.context.SessionScoped .: область действия сеанса сохраняется с момента установления сеанса до его завершения. Контекст сеанса является общим для всех запросов, которые происходят в одном сеансе HTTP. Это полезно, когда вы хотите сохранить данные для конкретного клиента для определенного сеанса.

3@javax.enterprise.context.ConversationScoped .: Объем беседы сохраняется в журнале в течение всего жизненного цикла. Область применения предусматривает 2 метода: Conversation.begin()и Conversation.end(). Эти методы должны вызываться явно, чтобы начать или закончить жизнь компонента.

4.@javax.enterprise.context.RequestScoped Область действия запроса недолговечна. Он начинается при отправке HTTP-запроса и заканчивается после отправки ответа клиенту. Если вы помещаете управляемый компонент в область запроса, новый экземпляр создается с каждым запросом. Стоит рассмотреть объем запроса, если вас беспокоит стоимость хранения области сеанса.

5@javax.faces.flow.FlowScoped .: Объем потока сохраняется до тех пор, пока поток существует. Поток может быть определен как содержащийся набор страниц (или представлений), которые определяют единицу работы. Область действия потока активна, пока пользователь перемещается в потоке.

6@javax.faces.view.ViewScoped .: Область видимости компонента сохраняется, пока отображается та же страница JSF. Как только пользователь переходит на другую страницу, бин выходит из области видимости.


Следующий традиционный ответ относится к версии JSF до 2.3

Начиная с 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] введите описание изображения здесь


Не могли бы вы уточнить, что вы подразумеваете под "методом недействительности в объекте HttpSession": invalidate()метод или недопустимый метод?
Александр Позднеев

1
Он немного староват и, возможно, опаздывает на ответ, но чтобы уточнить его: то, FacesContext.getCurrentInstance().getExternalContext().invalidateSession();что он вызывает в своем «бине выхода из системы» - это то, что он имеет в виду.
Роланд

1
это стало устаревшим ответом, на данный момент есть 8 областей
Ewoks

@KishorPrakash: сейчас уже 6 месяцев назад. ;-)
Kukeltje

@Kukeltje: Извините, я на это.
Кишор Пракаш
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.