Come scegliere l’ambito del bean giusto?

Ho notato che esistono diversi ambiti dei bean come:

@RequestScoped @ViewScoped @FlowScoped @SessionScoped @ApplicationScoped 

Qual è lo scopo di ciascuno? Come scelgo un ambito appropriato per il mio bean?

introduzione

Rappresenta lo scopo (la durata) del bean. Questo è più facile da capire se si ha familiarità con il funzionamento “sotto le copertine” di un’applicazione web di servlet di base: come funzionano le servlet? Istanziazione, sessioni, variabili condivise e multithreading .


@Request/View/Flow/Session/ApplicationScoped

Un bean @RequestScoped dura fino a un singolo ciclo di richiesta-risposta HTTP (si noti che anche una richiesta Ajax conta come una singola richiesta HTTP). Un bean @ViewScoped vive finché si interagisce con la stessa vista JSF da postback che richiamano i metodi di azione che restituiscono null / void senza alcun reindirizzamento / navigazione. Un bean @FlowScoped finché si sta navigando attraverso la raccolta di viste specificata registrata nel file di configurazione del stream. Un bean @SessionScoped fino a quando la sessione HTTP stabilita. Un bean @ApplicationScoped risiede fin tanto che l’applicazione web viene eseguita. Nota che il CDI @Model è fondamentalmente uno stereotipo per @Named @RequestScoped , quindi si applicano le stesse regole.

Quale ambito scegliere dipende esclusivamente dai dati (lo stato) che il bean detiene e rappresenta. Usa @RequestScoped per forms / presentazioni semplici e non-ajax. Utilizzare @ViewScoped per le viste dinamiche abilitate ajax (convalida, rendering, windows di dialogo basate su Ajax, ecc.). Utilizzare @FlowScoped per il modello “wizard” (“questionario”) di raccolta dei dati di input distribuiti su più pagine. Usa @SessionScoped per dati specifici del cliente, come le preferenze dell’utente e dell’utente (lingua, ecc.) @SessionScoped . Utilizzare @ApplicationScoped per dati / costanti di applicazione ampia, come elenchi a discesa che sono uguali per tutti, o bean gestiti senza variabili di istanza e con solo metodi.

Abusare di un bean @ApplicationScoped per i dati di sessione / vista / richiesta dell’ambito renderebbe la condivisione tra tutti gli utenti, in modo che chiunque altro possa vedere i dati degli altri semplicemente sbagliato. Abusare di un bean @SessionScoped per visualizzare / richiedere i dati dell’ambito potrebbe renderlo condiviso tra tutte le tabs / windows in una singola sessione del browser, in modo che l’utente finale possa riscontrare inconsistenze quando interagisce con ogni vista dopo il passaggio tra le tabs che è negativo per l’esperienza utente. Abusare di un bean @RequestScoped per i dati con scope vista renderebbe i dati con ambito vista reinizializzati su quelli predefiniti su ogni singolo (ajax) postback, causando probabilmente moduli non funzionanti ( vedere anche i punti 4 e 5 qui ). L’abuso di un bean @SessionScoped per dati con scope, sessione o applicazione e l’abuso di un bean @SessionScoped per dati con scope dell’applicazione non influisce sul client, ma occupa inutilmente la memoria del server ed è semplicemente inefficiente.

Si noti che l’ambito non dovrebbe essere scelto in base alle implicazioni in termini di prestazioni, a meno che non si disponga di un ingombro di memoria insufficiente e si voglia andare completamente privi di stato; avresti bisogno di usare esclusivamente i fagioli @RequestScoped e mantieni i parametri di richiesta per mantenere lo stato del client. Si noti inoltre che quando si dispone di una singola pagina JSF con dati con ambito diverso, è perfettamente valido inserirli in bean di backing separati in un ambito che corrisponda all’ambito dei dati. I bean possono semplicemente accedere l’un l’altro tramite @ManagedProperty in caso di bean gestiti JSF o @Inject nel caso di bean gestiti CDI.

Guarda anche:

  • Differenza tra l’ambito View e Request nei bean gestiti
  • Vantaggi dell’uso di JSF Faces Flow al posto del normale sistema di navigazione
  • Comunicazione in JSF2 – Ambiti di bean gestiti

@CustomScoped/NoneScoped/Dependent

Non è menzionato nella tua domanda, ma (legacy) JSF supporta anche @CustomScoped e @NoneScoped , che sono usati raramente nel mondo reale. @CustomScoped deve riferirsi a @CustomScoped personalizzata di Map in un ambito più ampio che ha sostituito Map#put() e / o Map#get() per avere un controllo più fine sulla creazione e / o distruzione dei bean.

JSF @NoneScoped e CDI @Dependent fondamentalmente vivono fino a una singola valutazione EL sul bean. Immagina un modulo di login con due campi di input che fanno riferimento a una proprietà bean e un pulsante di comando che fa riferimento a un’azione bean, quindi con tre espressioni EL totali, quindi verranno create effettivamente tre istanze. Uno con il nome utente impostato, uno con la password impostata e uno in cui viene richiamata l’azione. Normalmente vuoi usare questo scope solo sui bean che dovrebbero vivere fino a quando il bean viene iniettato. Quindi, se un @NoneScoped o @Dependent viene iniettato in un @SessionScoped , allora vivrà finché il bean @SessionScoped .

Guarda anche:

  • Scadenza dell’istanza di bean gestita specifica dopo l’intervallo di tempo
  • cosa non ha scope scope e quando usarlo?
  • Qual è il Managed Bean Scope predefinito in un’applicazione JSF 2?

Ambito di Flash

Come ultimo, JSF supporta anche l’ambito del flash. È supportato da un breve cookie di vita associato a una voce di dati nell’ambito della sessione. Prima del reindirizzamento, un cookie verrà impostato sulla risposta HTTP con un valore associato in modo univoco alla voce di dati nell’ambito della sessione. Dopo il reindirizzamento, la presenza del cookie dell’ambito Flash verrà verificata e la voce di dati associata al cookie verrà rimossa dall’ambito della sessione e inserita nell’ambito della richiesta della richiesta reindirizzata. Alla fine il cookie verrà rimosso dalla risposta HTTP. In questo modo, la richiesta reindirizzata ha accesso alla richiesta di dati con scope che sono stati preparati nella richiesta iniziale.

In realtà questo non è disponibile come scope bean gestito, ovvero non esiste nulla come @FlashScoped . L’ambito del flash è disponibile solo come mappa tramite ExternalContext#getFlash() nei bean gestiti e #{flash} in EL.

Guarda anche:

  • Come mostrare il messaggio dei volti nella pagina reindirizzata
  • Passa un object tra i bean @ViewScoped senza utilizzare i parametri GET
  • CDI mancante @ViewScoped e @FlashScoped

A partire da JSF 2.x ci sono 4 ambiti Bean:

  • @SessionScoped
  • @RequestScoped
  • @ApplicationScoped
  • @ViewScoped

Ambito della sessione: l’ambito della sessione persiste dal momento in cui una sessione viene stabilita fino alla chiusura della sessione. Una sessione termina se l’applicazione Web richiama il metodo invalidate sull’object HttpSession o se scade.

RequestScope: l’ambito della richiesta è di breve durata. Inizia quando una richiesta HTTP viene inviata e termina dopo che la risposta è stata inviata al client. Se si posiziona un bean gestito nell’ambito della richiesta, viene creata una nuova istanza con ogni richiesta. Vale la pena considerare l’ambito della richiesta se si è preoccupati del costo dell’archiviazione dell’ambito della sessione.

ApplicationScope: l’ambito dell’applicazione persiste per l’intera durata dell’applicazione Web. Tale ambito è condiviso tra tutte le richieste e tutte le sessioni. I bean gestiti vengono posizionati nell’ambito dell’applicazione se un singolo bean deve essere condiviso tra tutte le istanze di un’applicazione Web. Il bean viene creato quando viene richiesto per la prima volta da qualsiasi utente dell’applicazione e rimane attivo finché l’applicazione Web non viene rimossa dal server delle applicazioni.

ViewScope: l’ ambito di visualizzazione è stato aggiunto in JSF 2.0. L’ambito di un bean in vista persiste mentre la stessa pagina JSF viene nuovamente visualizzata. (Le specifiche JSF usano la vista termini per una pagina JSF.) Non appena l’utente naviga su una pagina diversa, il bean non rientra nello scope.

Scegli l’ambito in base alle tue esigenze.

Fonte: Core Java Server Faces 3rd Edition di David Geary e Cay Horstmann [Pagina n. 51 – 54] inserisci la descrizione dell'immagine qui