Notei que existem diferentes escopos de bean como:
@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped
Qual é o objetivo de cada um? Como escolho um escopo adequado para o meu bean?
jsf
jsf-2
scope
managed-bean
Valter Silva
fonte
fonte
Respostas:
Introdução
Representa o escopo (a vida útil) do bean. Isso é mais fácil de entender se você estiver familiarizado com o trabalho "oculto" de um aplicativo da web de servlet básico: Como os servlets funcionam? Instanciação, sessões, variáveis compartilhadas e multithreading .
@Request/View/Flow/Session/ApplicationScoped
Um
@RequestScoped
bean dura o tempo que um único ciclo de solicitação-resposta HTTP (observe que uma solicitação Ajax também conta como uma única solicitação HTTP). Um@ViewScoped
bean permanece enquanto você está interagindo com a mesma visualização JSF por postbacks que chamam métodos de ação retornandonull
/void
sem nenhuma navegação / redirecionamento. Um@FlowScoped
bean dura enquanto você estiver navegando pela coleção especificada de visualizações registradas no arquivo de configuração do fluxo. Um@SessionScoped
bean permanece enquanto a sessão HTTP estabelecida. Um@ApplicationScoped
bean dura enquanto o aplicativo da web é executado. Observe que o CDI@Model
é basicamente um estereótipo para@Named @RequestScoped
, então as mesmas regras se aplicam.Qual escopo escolher depende apenas dos dados (o estado) que o bean mantém e representa. Use
@RequestScoped
para formulários / apresentações simples e não-ajax. Use@ViewScoped
para visualizações dinâmicas ativadas por ajax (validação, renderização, caixas de diálogo, etc.). Use@FlowScoped
para o padrão "assistente" ("questionário") de coleta de dados de entrada espalhados por várias páginas. Use@SessionScoped
para dados específicos do cliente, como usuário conectado e preferências do usuário (idioma etc.). Use@ApplicationScoped
para dados / constantes abrangentes do aplicativo, como listas suspensas iguais para todos, ou beans gerenciados sem nenhuma variável de instância e possuindo apenas métodos.O abuso de um
@ApplicationScoped
bean para dados com escopo de sessão / exibição / solicitação faria com que ele fosse compartilhado entre todos os usuários, para que qualquer pessoa possa ver os dados um do outro, o que está errado. O abuso de um@SessionScoped
bean para dados com escopo de exibição / solicitação faria com que fosse compartilhado entre todas as guias / janelas em uma única sessão do navegador, para que o usuário final possa experimentar inconsistências ao interagir com todas as visualizações após alternar entre guias, o que é ruim para a experiência do usuário. O abuso de um@RequestScoped
bean para dados com escopo de exibição faria com que os dados com escopo fossem reinicializados para o padrão em cada postagem (ajax), causando possivelmente formulários que não funcionam ( veja também os pontos 4 e 5 aqui ). Abusar de um@ViewScoped
bean para dados com escopo de solicitação, sessão ou aplicativo e abusar de um@SessionScoped
O bean para dados com escopo do aplicativo não afeta o cliente, mas ocupa desnecessariamente a memória do servidor e é ineficiente.Observe que o escopo não deve ser escolhido com base nas implicações de desempenho, a menos que você realmente tenha pouco espaço na memória e queira ficar completamente sem estado; você precisaria usar exclusivamente
@RequestScoped
beans e mexer com parâmetros de solicitação para manter o estado do cliente. Observe também que quando você tem uma única página JSF com dados com escopo diferente, é perfeitamente válido colocá-los em beans de backup separados em um escopo que corresponda ao escopo dos dados. Os beans podem apenas acessar um ao outro via@ManagedProperty
no caso de beans gerenciados JSF ou@Inject
no caso de beans gerenciados CDI.Veja também:
@CustomScoped/NoneScoped/Dependent
Isso não é mencionado na sua pergunta, mas o JSF (legado) também suporta
@CustomScoped
e@NoneScoped
, que raramente são usados no mundo real. Ele@CustomScoped
deve se referir a umaMap<K, Bean>
implementação customizada em um escopo mais amplo que foi substituídoMap#put()
e / ouMap#get()
para ter um controle mais refinado da criação e / ou destruição do bean.O JSF
@NoneScoped
e o CDI@Dependent
vivem basicamente enquanto uma única avaliação EL no bean. Imagine um formulário de login com dois campos de entrada referentes a uma propriedade de bean e um botão de comando referente a uma ação de bean, portanto, com um total de três expressões EL, e efetivamente três instâncias serão criadas. Um com o nome de usuário definido, um com a senha definida e um no qual a ação é invocada. Você normalmente deseja usar esse escopo apenas em beans que devem permanecer enquanto o bean estiver sendo injetado. Portanto, se um@NoneScoped
ou@Dependent
for injetado em um@SessionScoped
, ele viverá tanto quanto o@SessionScoped
feijão.Veja também:
Escopo Flash
Por último, o JSF também suporta o escopo do flash. É apoiado por um cookie de curta duração, associado a uma entrada de dados no escopo da sessão. Antes do redirecionamento, um cookie será definido na resposta HTTP com um valor associado exclusivamente à entrada de dados no escopo da sessão. Após o redirecionamento, a presença do cookie do escopo flash será verificada e a entrada de dados associada ao cookie será removida do escopo da sessão e colocada no escopo da solicitação redirecionada. Finalmente, o cookie será removido da resposta HTTP. Dessa forma, a solicitação redirecionada tem acesso aos dados com escopo definido, que foram preparados na solicitação inicial.
Na verdade, isso não está disponível como um escopo de bean gerenciado, ou seja, não existe
@FlashScoped
. O escopo do flash está disponível apenas como um mapaExternalContext#getFlash()
nos beans gerenciados e#{flash}
no EL.Veja também:
fonte
@FlowScoped
(não é necessário iniciar / parar manualmente).ViewAccesscoped
eWindowScoped
ViewScoped
bean no MyFaces 2.2. Atualmente, estou enfrentando um problema com oViewScoped
bean e o Ajax, que publiquei aqui . No MyFaces JIRA, também há uma discussão sobre esse tópico.@RequestScoped
@SessionScoped
@ApplicationScoped
@ConversationScoped
por que os escopos que você descreve são diferentes?Desde o JSF 2.3, todos os escopos de bean definidos no pacote
javax.faces.bean
package foram descontinuados para alinhar os escopos ao CDI. Além disso, eles são aplicáveis apenas se seu bean estiver usando@ManagedBean
anotação. Se você estiver usando as versões JSF abaixo de 2.3, consulte a resposta herdada no final.No JSF 2.3, aqui estão os escopos que podem ser usados no JSF Backing Beans:
1
@javax.enterprise.context.ApplicationScoped
.: O escopo do aplicativo persiste por toda a duração do aplicativo da web. Esse escopo é compartilhado entre todas as solicitações e todas as sessões. Isso é útil quando você possui dados para todo o aplicativo.2
@javax.enterprise.context.SessionScoped
.: O escopo da sessão persiste desde o momento em que uma sessão é estabelecida até o término da sessão. O contexto da sessão é compartilhado entre todas as solicitações que ocorrem na mesma sessão HTTP. Isso é útil quando você não salva dados de um cliente específico para uma sessão específica.3
@javax.enterprise.context.ConversationScoped
.: O escopo da conversa persiste como o log que o bean vive. O escopo fornece 2 métodos:Conversation.begin()
eConversation.end()
. Esses métodos devem ser chamados explicitamente, para iniciar ou finalizar a vida útil de um bean.4
@javax.enterprise.context.RequestScoped
.: O escopo da solicitação é de curta duração. Inicia quando uma solicitação HTTP é enviada e termina após a resposta ser enviada de volta ao cliente. Se você colocar um bean gerenciado no escopo da solicitação, uma nova instância será criada com cada solicitação. Vale a pena considerar o escopo da solicitação se você estiver preocupado com o custo do armazenamento do escopo da sessão.5
@javax.faces.flow.FlowScoped
.: O escopo do fluxo persiste enquanto o fluxo permanecer. Um fluxo pode ser definido como um conjunto contido de páginas (ou visualizações) que definem uma unidade de trabalho. O escopo definido como fluxo está ativo enquanto o usuário navega no fluxo.6
@javax.faces.view.ViewScoped
.: Um escopo do bean no modo de exibição persiste enquanto a mesma página JSF é exibida novamente. Assim que o usuário navega para uma página diferente, o bean fica fora do escopo.A resposta legada a seguir aplica a versão JSF anterior à 2.3
Fonte: Core Java Server Faces 3rd Edition por David Geary e Cay Horstmann [Página no. 51 - 54]
fonte
invalidate()
método ou método inválido?FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
ser invocado no seu "logout bean" é o que ele quer dizer.