Безопасны ли потоки управляемых компонентов JSF 2.x @ViewScoped? - PullRequest
17 голосов
/ 14 сентября 2011

Я пару часов гуглял по этому вопросу, но не до конца.

WELD-документы и спецификации CDI достаточно ясны в отношении безопасности потоков предоставленных областей.

Например:

  • Область применения - небезопасно

  • Область сеанса - небезопасно

  • Область запроса - безопасна, всегда связана с одной нитью

  • Область разговора - безопасная (благодаря сериализации доступа WELD-прокси из нескольких потоков запросов)

Я ничего не могу найти в области видимости, определенной в JSF 2.x.

Он находится примерно в том же сегменте, что и область беседы, так как очень возможно, чтобы несколько запросов одновременно попадали в область действия, несмотря на то, что она привязана к одному представлению / пользователю. Что я не знаю, так это то, что реализация JSF сериализует доступ к компоненту из нескольких запросов.

Кто-нибудь знает спецификацию или реализации Morraja / MyFaces, которые могут это прояснить?

Ответы [ 2 ]

17 голосов
/ 14 сентября 2011

Область просмотра с нормальным использованием потока безопасна. Может использоваться только одним окном / вкладкой браузера. А именно, оно имеет уникальное скрытое поле ввода, которое задается в начальном GET-запросе. Каждый постбэк в одном и том же виде будет использовать один и тот же bean-объект области видимости. Сам браузер уже «синхронизирует» запросы обратной передачи в том же окне / вкладке. Новое окно / вкладка браузера фактически является новым GET-запросом и, следовательно, создает новое и полностью независимое представление.

Что касается постбэков ajax, они по спецификации поставлены в очередь. Это упомянуто в главе 13.3.2 спецификации JSF 2 :

13.3.2 Очередь запросов Ajax

Все запросы Ajax должны быть помещены в очередь запросов на стороне клиента, прежде чем они будут отправлены в сервер для обеспечения обработки запросов Ajax в порядке их отправки. Запрос, который ожидал в очереди самый длинный следующий запрос будет отправлен. После отправки запроса функция обратного вызова Ajax-запроса должна удалить запрос из очереди (также известной как снятие очереди). Если запрос выполнен успешно, он должен быть удален из очереди. Если произошла ошибка, клиент должен быть уведомлен, но запрос все равно должен быть удален из очереди, поэтому следующий запрос можно отправить. Следующий запрос (самый старый запрос в очереди) должен быть отправлен. Обратитесь к jsf.ajax.request Документация JavaScript для получения дополнительной информации об очереди запросов Ajax.

Только при использовании PrimeFaces организация очереди может быть отключена с помощью <p:ajax async="true">. При использовании этого в комбинации с bean-объектами видимости безопасность потоков должна быть пересмотрена так же, как и для bean-объектов сессий.

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

3 голосов
/ 14 сентября 2011

ViewScoped бобы хранятся в «представлении» Map, которое создается для каждого UIViewRoot.Когда два одновременных запроса обрабатываются средой выполнения JSF, обычно маловероятно, что для этих запросов будет создан / восстановлен один и тот же экземпляр UIViewRoot, поскольку параметр формы javax.faces.ViewState в HTTP-запросе используется для определения, существует ли существующий UIViewRoot экземпляр должен быть восстановлен или нет (при обратной передаче).Как указал BalusC, два разных окна браузера приведут к созданию двух разных bean-объектов области видимости, поскольку базовые параметры ViewStates различны для обеих вкладок браузера (если вы отправляете два разных HTTP-запроса и браузер использует ответ каждого из них).для отображения отдельных вкладок вместо использования кэшированной копии).

Однако часть о безопасности потоков не ограничивается вкладками / окнами браузера.В среде выполнения JSF (по крайней мере, в Mojarra) нет встроенного механизма, который синхронизировал бы доступ к UIViewRoot и карте представления, если два запроса HTTP (и, следовательно, два потока) представляют одинаковое значение javax.faces.ViewState в запросе кобрабатываться контейнером.Следовательно, bean-объекты вида видимости не являются поточно-ориентированными по своей природе, и к ним также нет доступа потокобезопасным способом.Вы могли бы подтвердить это, воспроизводя запросы с одинаковыми значениями javax.faces.ViewState и наблюдая за поведением контейнера / JVM, когда контейнер за короткое время получает несколько таких запросов (что приводит к возможности одновременного доступа к одному и тому же UIViewRootэкземпляр несколькими потоками).

...