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?
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?
Réponses:
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 renvoyant null
/ 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.
@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 une Map<K, Bean>
implémentation personnalisée dans une portée plus large qui a remplacé Map#put()
et / ou Map#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.
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 les ExternalContext#getFlash()
beans gérés et #{flash}
EL.
@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 le ViewScoped
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()
et Conversation.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
Depuis JSF 2.x, il existe 4 étendues de bean:
- @SessionScoped
- @RequestScoped
- @ApplicationScoped
- @ViewScoped
Étendue de la session: l' étendue de la session persiste à partir du moment où une session est établie jusqu'à la fin de la session. Une session se termine si l'application Web appelle la méthode invalidate sur l'objet HttpSession, ou si elle expire.
RequestScope: 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.
ApplicationScope: la portée 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. Vous placez les beans gérés dans la portée de l'application si un seul bean doit être partagé entre toutes les instances d'une application Web. Le bean est construit lorsqu'il est demandé pour la première fois par n'importe quel utilisateur de l'application, et il reste actif jusqu'à ce que l'application Web soit supprimée du serveur d'applications.
ViewScope: la portée de la vue a été ajoutée dans JSF 2.0. Un bean dans la portée de la vue persiste pendant que la même page JSF est ré-affichée. (La spécification JSF utilise la vue terminologique pour une page JSF.) Dès que l'utilisateur accède à une autre page, le bean sort du domaine.
Choisissez la portée que vous avez basée sur votre condition.
Source: Core Java Server Faces 3rd Edition par David Geary & Cay Horstmann [Page no. 51 - 54]
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.