J'ai remarqué qu'il existe différentes portées de haricots comme:
@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped
Quel est le but de chacun? Comment choisir une étendue appropriée pour mon bean?
jsf
jsf-2
scope
managed-bean
Valter Silva
la source
la source
Réponses:
introduction
Il représente la portée (la durée de vie) du bean. Ceci est plus facile à comprendre si vous êtes familiarisé avec le fonctionnement «sous les couvertures» d'une application Web de servlet de base: comment fonctionnent les servlets? Instanciation, sessions, variables partagées et multithreading .
@Request/View/Flow/Session/ApplicationScoped
Un
@RequestScoped
bean vit aussi longtemps qu'un seul cycle de demande-réponse HTTP (notez qu'une demande Ajax compte aussi comme une seule demande HTTP). Un@ViewScoped
bean vit tant que vous interagissez avec la même vue JSF par des publications qui appellent des méthodes d'action renvoyantnull
/void
sans navigation / redirection. Un@FlowScoped
bean vit tant que vous parcourez la collection spécifiée de vues enregistrées dans le fichier de configuration de flux. Un@SessionScoped
bean vit aussi longtemps que la session HTTP établie. Un@ApplicationScoped
bean vit aussi longtemps que l'application Web s'exécute. Notez que le CDI@Model
est fondamentalement un stéréotype pour@Named @RequestScoped
, donc les mêmes règles s'appliquent.L'étendue à choisir dépend uniquement des données (l'état) que le bean détient et représente. Utilisez
@RequestScoped
pour les formulaires / présentations simples et non ajax. À utiliser@ViewScoped
pour les vues dynamiques riches en ajax (validation basée sur ajax, rendu, boîtes de dialogue, etc.). À utiliser@FlowScoped
pour le modèle "assistant" ("questionnaire") de collecte des données d'entrée réparties sur plusieurs pages. Utilisation@SessionScoped
pour les données spécifiques au client, telles que l'utilisateur connecté et les préférences de l'utilisateur (langue, etc.). Utilisation@ApplicationScoped
pour les données / constantes à l'échelle de l'application, telles que les listes déroulantes qui sont les mêmes pour tout le monde, ou les beans gérés sans variables d'instance et n'ayant que des méthodes.L'utilisation abusive d'un
@ApplicationScoped
bean pour les données de portée de session / vue / demande le ferait être partagé entre tous les utilisateurs, de sorte que n'importe qui d'autre puisse voir les données les uns des autres, ce qui est tout simplement faux. L'utilisation abusive d'un@SessionScoped
bean pour les données de portée vue / demande le ferait être partagé entre tous les onglets / fenêtres dans une seule session de navigateur, de sorte que l'utilisateur final peut rencontrer des incohérences lors de l'interaction avec chaque vue après avoir basculé entre les onglets, ce qui est mauvais pour l'expérience utilisateur. L'utilisation abusive d'un@RequestScoped
bean pour les données de portée de vue entraînerait la réinitialisation des données de portée de vue par défaut sur chaque publication (ajax), provoquant éventuellement des formulaires non fonctionnels ( voir également les points 4 et 5 ici ). Utilisation abusive d'un@ViewScoped
bean pour des données de portée de demande, de session ou d'application et utilisation abusive d'un@SessionScoped
Le bean pour les données de portée d'application n'affecte pas le client, mais il occupe inutilement la mémoire du serveur et est tout simplement inefficace.Notez que la portée ne doit pas être choisie en fonction des implications en termes de performances, à moins que vous n'ayez vraiment une faible empreinte mémoire et que vous souhaitiez devenir complètement sans état; vous auriez besoin d'utiliser exclusivement des
@RequestScoped
beans et de jouer avec les paramètres de requête pour maintenir l'état du client. Notez également que lorsque vous avez une seule page JSF avec des données de portée différente, il est parfaitement valide de les placer dans des beans de sauvegarde distincts dans une étendue correspondant à l'étendue des données. Les beans peuvent simplement accéder les uns aux autres via@ManagedProperty
en cas de beans gérés JSF ou@Inject
en cas de beans gérés CDI.Voir également:
@CustomScoped/NoneScoped/Dependent
Ce n'est pas mentionné dans votre question, mais (hérité) JSF prend également en charge
@CustomScoped
et@NoneScoped
, qui sont rarement utilisés dans le monde réel. Le@CustomScoped
doit référencer uneMap<K, Bean>
implémentation personnalisée dans une portée plus large qui a remplacéMap#put()
et / ouMap#get()
afin d'avoir un contrôle plus fin sur la création et / ou la destruction du bean.Le JSF
@NoneScoped
et le CDI@Dependent
vivent essentiellement aussi longtemps qu'une seule évaluation EL sur le bean. Imaginez un formulaire de connexion avec deux champs de saisie faisant référence à une propriété de bean et un bouton de commande faisant référence à une action de bean, donc avec au total trois expressions EL, puis en fait trois instances seront créées. Un avec le nom d'utilisateur défini, un avec le mot de passe défini et un sur lequel l'action est invoquée. Vous souhaitez normalement utiliser cette étendue uniquement sur les beans qui doivent vivre aussi longtemps que le bean où il est injecté. Donc, si un@NoneScoped
ou@Dependent
est injecté dans un@SessionScoped
, il vivra aussi longtemps que le@SessionScoped
haricot.Voir également:
Portée Flash
Comme précédemment, JSF prend également en charge la portée flash. Il est soutenu par un cookie vivant court qui est associé à une entrée de données dans la portée de la session. Avant la redirection, un cookie sera défini sur la réponse HTTP avec une valeur qui est uniquement associée à l'entrée de données dans la portée de la session. Après la redirection, la présence du cookie de portée flash sera vérifiée et l'entrée de données associée au cookie sera supprimée de la portée de la session et placée dans la portée de la demande de la demande redirigée. Enfin, le cookie sera supprimé de la réponse HTTP. De cette façon, la demande redirigée a accès aux données de portée de demande qui ont été préparées dans la demande initiale.
Ce n'est en fait pas disponible en tant que portée de bean géré, c'est-à-dire qu'il n'y a rien de tel
@FlashScoped
. La portée flash est uniquement disponible sous forme de carte via lesExternalContext#getFlash()
beans gérés et#{flash}
EL.Voir également:
la source
@FlowScoped
(pas besoin de le démarrer / l'arrêter manuellement).ViewAccesscoped
etWindowScoped
ViewScoped
bean dans MyFaces 2.2. Je suis actuellement confronté à un problème avec leViewScoped
bean et l'Ajax, que j'ai publié ici . Dans MyFaces JIRA, il y a aussi une discussion sur ce sujet.@RequestScoped
@SessionScoped
@ApplicationScoped
@ConversationScoped
pourquoi les étendues que vous décrivez sont différentes?Depuis JSF 2.3, toutes les étendues de bean définies dans package
javax.faces.bean
package ont été déconseillées pour aligner les étendues avec CDI. De plus, ils ne sont applicables que si votre bean utilise des@ManagedBean
annotations. Si vous utilisez des versions JSF inférieures à 2.3, reportez-vous à la réponse héritée à la fin.De JSF 2.3 voici des étendues qui peuvent être utilisées sur les Jing Backing Beans:
1
@javax.enterprise.context.ApplicationScoped
.: L'étendue de l'application persiste pendant toute la durée de l'application Web. Cette portée est partagée entre toutes les demandes et toutes les sessions. Ceci est utile lorsque vous disposez de données pour l'ensemble de l'application.2
@javax.enterprise.context.SessionScoped
.: La portée de la session persiste à partir du moment où une session est établie jusqu'à la fin de la session. Le contexte de session est partagé entre toutes les demandes qui se produisent dans la même session HTTP. Ceci est utile lorsque vous ne souhaitez pas enregistrer de données pour un client spécifique pour une session particulière.3
@javax.enterprise.context.ConversationScoped
.: La portée de la conversation persiste aussi longtemps que le bean vit. La portée propose 2 méthodes:Conversation.begin()
etConversation.end()
. Ces méthodes doivent être appelées explicitement, soit pour démarrer soit pour mettre fin à la vie d'un bean.4
@javax.enterprise.context.RequestScoped
.: La portée de la demande est de courte durée. Il démarre lorsqu'une demande HTTP est soumise et se termine une fois la réponse renvoyée au client. Si vous placez un bean géré dans la portée de la demande, une nouvelle instance est créée avec chaque demande. Il vaut la peine d'envisager la portée de la demande si vous êtes préoccupé par le coût du stockage de la portée de la session.5
@javax.faces.flow.FlowScoped
.: La portée du Flow persiste aussi longtemps que le Flow dure. Un flux peut être défini comme un ensemble contenu de pages (ou vues) qui définissent une unité d'oeuvre. Le flux délimité est actif tant que l'utilisateur navigue dans le flux.6
@javax.faces.view.ViewScoped
.: Un bean dans la portée de la vue persiste pendant que la même page JSF est ré-affichée. Dès que l'utilisateur accède à une autre page, le bean sort du cadre.La réponse héritée suivante applique la version JSF avant 2.3
Source: Core Java Server Faces 3rd Edition par David Geary & Cay Horstmann [Page no. 51 - 54]
la source
invalidate()
méthode ou méthode non valide?FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
être invoqué dans votre "bean de déconnexion" est ce qu'il veut dire.