@SessionScoped
обозначает область действия, а @Stateful
— это то, что мы сейчас назвали бы стереотипом. @Stateful
добавляет ряд сервисов к бину, среди которых транзакционное поведение и пассивация.
Однако центральное место в @Stateful
занимает его поведение во время сеанса, которое действительно пересекается с областью действия сеанса.
Разница в том, что область сеанса привязана к сеансу HTTP, тогда как @Stateful
является открытым сеансом, управляемым пользователем, а его время жизни управляется клиентом, у которого есть ссылка на прокси-компонент bean.
@Stateful
удаленные bean-компоненты, в которых изначально были двоичные (RMI) составные части сервлетов. Там, где сервлеты прослушивали удаленные HTTP-запросы от браузера, @Stateful
удаленные компоненты прослушивали удаленные RMI-запросы от апплетов (и более поздних клиентов Swing).
К сожалению, между ними было много несоответствий. Сервлет был просто прослушивателем HTTP, в то время как @Stateful
bean-компоненты автоматически добавляли множество других функций. Сервлет также разделяет сеанс со всеми другими сервлетами, а также совместно использует пространство имен компонентов Java EE со всеми другими сервлетами в войне, в то время как с @Stateful
каждый отдельный компонент имеет свое собственное пространство имен сеанса и компонента.
С появлением локальных компонентов в EJB 2 и резким сокращением количества клиентов Swing/Applet для удаленного взаимодействия EJB функция сеанса, который поддерживается для компонента @Stateful
, стала менее ясной.
Я думаю, будет справедливо сказать, что @Stateful
просто не так часто используется в наши дни. Для веб-приложения сеанс HTTP почти всегда является ведущим, что означает использование области сеанса и локальных компонентов @Stateless
и/или компонентов CDI для бизнес-логики.
В некоторых случаях бины @Stateful
необходимы для их естественной поддержки расширенного контекста персистентности из JPA и для их функций пассивации (Servlet не имеет стандартизированного механизма пассивации). Обратите внимание, что @Stateful
и @SessionScoped
(или многие другие области) можно комбинировать. Преимущество их объединения в том, что пользовательскому коду больше не нужно управлять временем жизни, а контейнер управляет этим.
Примерно такая же история и с @ApplicationScoped
и @Singleton
, но без наследства (@Singleton
- вещь довольно новая). @ApplicationScoped
— это просто область, в то время как @Singleton
— это тип компонента (стереотип, если хотите), который не только дает вам поведение в области приложения, но также снова предоставляет вам транзакционное поведение с автоматической блокировкой (которую можно настроить с помощью @Lock
) и с нетерпеливым строительным поведением (через @Startup
).
Хотя @Stateful
и @Singleton
сами по себе довольно удобны, текущий путь вперед в Java EE, похоже, состоит в том, чтобы разложить эти встроенные стереотипы на отдельно используемые аннотации, и кто знает, возможно, однажды они станут настоящими стереотипами CDI, состоящими из этих разложенных аннотаций.
person
Arjan Tijms
schedule
09.06.2014