JSF – Entendendo e utilizando corretamente os escopos

O JSF é um Framework que tem um comportamento “component based” (baseado em componentes). De forma bem resumida, isso quer dizer que a página irá buscar a informação no ManagedBean, que por sua vez tem um tipo de escopo definido, ideal para cada situação.
Mas para saber em que situação usar cada escopo, é necessário entender como cada um deles funciona, o escopo determina o ciclo de vida de um ManagedBean, quando uma nova instância de qualquer ManagedBean será criada ou destruída.

Neste post irei abordar como funciona os principais tipos de escopos, tendo foco maior nos mais usados, ilustrando com diagramas e exemplos, e ao final do post tem um vídeo de demonstrando o funcionamento dos escopos mais utilizados e deixei um link para um projeto de exemplo.

@RequestScoped

É o escopo padrão caso você não informe um, ele funciona como um simples HTTP request, é descartado ao fim de cada requisição, o ManagedBean não manterá seu estado entre as solicitações/requisições HTTP que o usuário fizer.

RequestScopedA cada requisição uma nova instância do ManagedBean sera criada, usada e descartada, desta maneira não há compartilhamento das informações do ManagedBean entre as requisições.

O melhor uso para utilização de um ManagedBean no escopo de request é em telas que não necessitam de chamada AJAX, ou em de algum objeto salvo na memória.
Considere uma situação onde não é necessário nenhuma informação adicional de um objeto na memória, basta enviar os dados presentes do formulário que um objeto será criado e estará pronto para ser persistido no banco de dados.

Um outro exemplo é um ManagedBean de login, onde os dados do usuário (login e senha) seriam processados, e ao fim do processamento o usuário seria encaminhado para página que deseja acessar ou permaneceria na mesma página de login caso as informações não forem validas, não seria necessário manter o estado do ManagedBean.

 

@SessionScoped

Tem o mesmo comportamento da sessão web (HttpSession), o estado do ManagedBean é mantido até o fim da sessão do usuário. É preciso ter muito cuidado ao utilizar o SessionScoped, pois ele será mantido em memória até que o usuário termine a sessão. Imagine uma aplicação com 1000 sessões de usuários ativos, e cada sessão mantendo um ManagedBean com escopo SessionScoped, imagine agora que cada ManagedBean tem uma lista com 300 objetos, seriam 300000 objetos mantidos em memória, nem preciso dizer que vai chegar uma hora que vai dar M…..

Sessionscoped

O SessionScoped é muito útil, mas pode causar muita dor de cabeça se mal utilizado. Ele é ideal para guardar informações da sessão, dados do usuário, páginas acessadas, horários etc.

 

@ViewScoped

É um tipo de escopo que fica entre o RequestScoped e o SessionScoped. O MangedBean vai manter seu estado enquanto o usuário permanecer na mesma página. Qualquer navegação para outra página ou até mesmo um redirect para a mesma página ocasionara o fim do ManagedBean.

Viewscoped

É um escopo muito útil para páginas com várias chamadas AJAX, podendo abrir vários dialogs ou fazer varias requisições que os dados serão mantidos, desde que não haja nenhuma navegação para qualquer página, inclusive a atual.

É preciso ter em mente que usando esse tipo de escopo estamos suscetíveis a problemas que podem ocorrer com relação ao acesso de vários usuários ao banco de dados simultaneamente. Imagine que o usuário Carlos abre um produto para editar, e antes de finalizar a edição ele sai para tomar água deixando a tela aberta, nesse intervalo o usuário Raul acessa o sistema em outro computador e edita o mesmo produto e salva, quando Carlos voltar para finalizar a edição, as alterações do Raul serão perdidas. Em alguns frameworks como o JPA esse problema é facilmente tratado através do “lock otimista” e “lock pessimistic”, mas isso é assunto para outro post.

 

@ConversationScoped

Só pode ser usando com CDI, e controle é feito manualmente, ele funciona basicamente como uma transação de banco de dados. São necessários comandos para iniciar e para finalizar o seu ciclo de vida. O ManagedBean do tipo ConversationScoped tem apenas dois estados, transient e long running. O estado será transient antes do início e após o fim da conversação.

É ideal para telas que realizam muitas chamadas AJAX, e os dados precisam ser mantidos até um determinado momento, é possível navegar entre diferentes páginas que os objetos serão mantidos. Caso a sessão do usuário ter-
mine, o ManagedBean do tipo ConversationScoped será eliminado da sessão.

ConversationScoped

@AplicationScoped

Funciona como um Singleton, ou seja mantem apenas uma única instância na memória em toda a aplicação, todo usuário tem acesso ao mesmo ManagedBean, logo não é aconselhável guardar informações de usuários com ApplicationScoped.

As vezes é necessário que um ManagedBean com esse escopo seja iniciado antes de todos os outros, para isso basta adicionar a seguinte configuração: “@ManagedBean(eager = true)”, com isso ele sera iniciado antes que o usuário entre em qualquer tela da aplicação.

Usecasediagram1

 

@Dependent

Só pode ser usando com CDI, este escopo não possui um comportamento próprio, ele vai herdar o comportamento do ManagedBean em que for injetado.

 

@NoneScoped

Dura apenas um chamada da EL e depois é eliminado da memória.
É um escopo extremamente curto, e será usado em tarefas muito especificas.

 

https://github.com/marcelodd/JSFEscopos

 

 

Sobre o Autor

Marcelo é formado em Tecnologia em Análise e Desenvolvimento de Sistemas no Instituto Federal de São Paulo, programador em várias linguagens de programação e apaixonado por tecnologia, acredita que o conhecimento só vale se puder ser compartilhado.