Разница между @SessionScoped (CDI) и @Stateful (Java EE)

#jakarta-ee #annotations #cdi #stateful #session-scope

#джакарта-ee #примечания #cdi #с сохранением состояния #область действия сеанса

Вопрос:

Я узнал, что компоненты CDI могут использоваться в разных областях на основе веб-приложений (только там, верно?). Например: @RequestScoped, @SessionScoped и так далее. @SessionScoped хранит данные в управляемом компоненте в течение всего сеанса браузера. Это звучит логично, потому что имя аннотации описывает, что оно делает. Однако — теперь я более внимательно посмотрел на сеансовые компоненты EJB. До сих пор я знаю, что такое может иметь одно из трех состояний: @Stateless, @Stateful и @Singleton. Для меня похоже, что существует прямая сопоставимость между ними и аннотациями компонента CDI: @RequestScoped -> @Stateless, @SessionScoped -> @Stateful , @ApplicationScoped -> @Singleton . Но поскольку я изучал некоторые примеры, я нашел компонент, который включает в себя как аннотацию @Stateful, так и аннотацию @SessionScoped . Я искал объяснение, но не нашел ни одного понятного ответа. Итак, в чем именно разница? Почему я должен использовать обе аннотации? Спасибо.

Комментарии:

1. В первую очередь: CDI @SessionScoped привязан к текущему сеансу HTTP; @Stateful не распознает HTTP-сеанс, скорее, он просто остается активным в пуле без учета состояния сеансов клиента. Существуют и другие различия, основанные на вариантах использования, но это основное различие

Ответ №1:

Компоненты CDI могут использоваться в разных областях на основе веб-приложений (только там, верно?).

Неправильно. Компоненты CDI можно использовать в любом месте, где вы пожелаете — подключение / связь с БД, деловая логика, программирование на основе событий даже в Java SE (Weld, эталонная реализация CDI, предлагает это даже сейчас). Однако, в частности @SessionScoped , bean имеет гораздо больше смысла в HTTP-сеансах, чем где-либо еще. Но все же вы можете представить (и использовать) сеанс как заданный период времени с отмеченными началом и концом. И в этих границах существует сеанс — не обязательно HTTP-сеанс, но он самый очевидный.

прямая сопоставимость между ними и аннотациями компонента CDI: @RequestScoped -> @Stateless, @SessionScoped -> @Stateful , @ApplicationScoped -> @Singleton.

Снова неправильно. EJB связаны только с веб-коммуникацией, CDI — нет. Также на основе выбранной вами аннотации вы также выбираете контейнер (CDI / EJB), который будет отвечать за этот компонент. CDI интегрирует все компоненты EJB (создавая прокси и делая его «кажущимся» компонентом CDI — позволяя вам использовать материал CDI внутри компонента EJB).

Теперь, например, @Stateless в CDi / Weld внутренне представлено как @Dependent область видимости, а не как @RequestScoped , потому @Stateless что компоненты в EJB используются повторно, и вы не можете точно определить их состояние. При @RequestScoped использовании in CDI вы активируете контекст запроса (давайте придерживаться HTTP, поэтому, отправляя что-то, вы активируете его), который запускает создание всех @RequestScoped компонентов. После запроса все эти компоненты уничтожаются и больше никогда не используются. Таким образом, вы можете полностью полагаться на то, что вы помещаете внутрь, и вы также можете быть уверены, что оно не будет работать после запроса.

Другая история — @ApplicationScoped versus @Singleton . Они действительно очень похожи, и наиболее существенной деталью, вероятно, будет тот факт, что CDI создает свои собственные прокси-компоненты. Но это было бы слишком подробно для этого вопроса, я думаю, теперь вы можете считать их сопоставимыми.

Разница между @SessionScoped (CDI) и @Stateful (Java EE)

Теперь, наконец, к первоначальному вопросу. Я думаю, чтобы понять эти различия в целом, вам нужно понять тот факт, что CDI работает с контекстами. Он всегда активирует контекст (в данном случае контекст сеанса), и в этот момент появляется набор @SessionScoped компонентов, и вы можете общаться с ними, и у них есть значения, состояния и т.д. Контексты пересекаются, поэтому в одно и то же время может существовать контекст запроса, и контекст приложения точно существует. Таким образом, мы можем сказать, что @SessionScoped это привязано к сеансу и контролируется контейнером, в то время @Stateful как предлагает вам управляемый пользователем сеанс с его временем жизни, управляемым клиентом, а также добавляет множество других функций в дополнение к этому.

Причина, по которой вы иногда можете видеть обе аннотации в одном компоненте, заключается в том, что люди объединяют их, чтобы получить лучшее из обоих миров — управляемый жизненный цикл контейнера и добавленные функции. Но обратите внимание, что, хотя @Stateful в наши дни он используется не так часто (обычно имеет больше смысла выбирать @Stateless ), @SessionScope он гораздо более универсален и вписывается практически в любой сценарий, основанный на сеансе.

Надеюсь, это прольет хоть какой-то свет, боюсь, это очень сложная тема.

Ответ №2:

Компоненты EJB по умолчанию предоставляют вам транзакцию, компоненты CDI — нет.

Я думаю, в этом разница

Комментарии:

1. Как компоненты CDI, так и компоненты EJB являются управляемыми компонентами. Они разделяют много базовых вещей, и правильно, что компонент EJB поддерживает транзакцию. Но это не может быть единственной разницей, иначе не было бы смысла использовать как «@Stateful», так и «@SessionScoped». 😉