Безопасны ли потоки управляемых компонентов JSF 2.x @ViewScoped?
Я пару часов гуглял по этому вопросу, но не до конца.
Документы WELD и спецификации CDI достаточно ясны в отношении безопасности потоков предоставленных областей.
Например:
Область применения - небезопасно
Session Scope - не безопасно
Область запросов - безопасная, всегда привязана к одному потоку
Область разговора - безопасная (благодаря сериализации доступа WELD-прокси из нескольких потоков запросов)
Я не могу найти ничего в области видимости, определенной в JSF 2.x.
Он находится примерно в том же сегменте, что и область разговора, так как очень возможно, чтобы несколько запросов одновременно попадали в область, несмотря на то, что она привязана к одному представлению / пользователю. Что я не знаю, так это то, что реализация JSF сериализует доступ к бину из нескольких запросов.
Кто-нибудь знает спецификацию или реализации Morraja/MyFaces, которые могут это прояснить?
2 ответа
Область видимости - с нормальным использованием потокобезопасного. Может использоваться только одним окном / вкладкой браузера. А именно, это связано с уникальным скрытым полем ввода, которое устанавливается в начальном 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-объектов сессий.
Смотрите также:
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
экземпляр несколькими потоками).