¿Cómo elegir el alcance de frijol correcto?

Respuestas:

485

Introducción

Representa el alcance (la vida útil) del bean. Esto es más fácil de entender si está familiarizado con el funcionamiento "oculto" de una aplicación web de servlet básica: ¿Cómo funcionan los servlets? Instanciación, sesiones, variables compartidas y multihilo .


@Request/View/Flow/Session/ApplicationScoped

Un @RequestScopedbean vive tanto como un solo ciclo de solicitud-respuesta de HTTP (tenga en cuenta que una solicitud de Ajax también cuenta como una sola solicitud de HTTP). Un @ViewScopedbean vive mientras interactúa con la misma vista JSF mediante devoluciones que llaman métodos de acción que regresan null/ voidsin navegación / redirección. Un @FlowScopedbean vive mientras navega por la colección especificada de vistas registradas en el archivo de configuración de flujo. Un @SessionScopedbean vive tanto como la sesión HTTP establecida. Un @ApplicationScopedbean vive mientras se ejecute la aplicación web. Tenga en cuenta que el CDI @Modeles básicamente un estereotipo@Named @RequestScoped , por lo que se aplican las mismas reglas.

El alcance a elegir depende únicamente de los datos (el estado) que el bean contiene y representa. Úselo @RequestScopedpara formularios / presentaciones simples y no ajax. Úselo @ViewScopedpara vistas dinámicas habilitadas con ajax (validación, renderizado, diálogos, etc.). Se utiliza @FlowScopedpara el patrón de "asistente" ("cuestionario") de recopilación de datos de entrada distribuidos en varias páginas. Utilícelo @SessionScopedpara datos específicos del cliente, como el usuario conectado y las preferencias del usuario (idioma, etc.). Úselo @ApplicationScopedpara datos / constantes de toda la aplicación, como listas desplegables que son iguales para todos, o beans administrados sin ninguna variable de instancia y que solo tienen métodos.

Abusar de un @ApplicationScopedbean para datos de alcance de sesión / vista / solicitud haría que se compartiera entre todos los usuarios, de modo que cualquier otra persona pueda ver los datos de los demás, lo cual es simplemente incorrecto. Abusar de un @SessionScopedbean para ver / solicitar datos con alcance haría que se compartiera entre todas las pestañas / ventanas en una sola sesión del navegador, por lo que el usuario final puede experimentar inconsistencias al interactuar con cada vista después de cambiar entre pestañas, lo que es malo para la experiencia del usuario. Abusar de un @RequestScopedbean para ver los datos de ámbito hará que los datos de ámbito de vista se reinicialicen a los valores predeterminados en cada devolución de datos (ajax), lo que puede causar formas que no funcionen ( ver también los puntos 4 y 5 aquí ). Abusar de un @ViewScopedbean para datos de ámbito de solicitud, sesión o aplicación, y abusar de un@SessionScoped Bean para los datos de ámbito de aplicación no afecta al cliente, pero ocupa innecesariamente la memoria del servidor y es ineficiente.

Tenga en cuenta que el alcance no debe elegirse en función de las implicaciones de rendimiento, a menos que realmente tenga una huella de memoria baja y desee pasar completamente sin estado; necesitaría usar exclusivamente @RequestScopedbeans y violín con parámetros de solicitud para mantener el estado del cliente. También tenga en cuenta que cuando tiene una sola página JSF con datos de alcance diferente, entonces es perfectamente válido ponerlos en beans de respaldo separados en un ámbito que coincida con el alcance de los datos. Los beans solo pueden acceder entre sí a través @ManagedPropertyde los beans administrados por JSF o @Injecten el caso de los beans administrados por CDI.

Ver también:


@CustomScoped/NoneScoped/Dependent

No se menciona en su pregunta, pero JSF (heredado) también es compatible @CustomScopedy @NoneScoped, que rara vez se usa en el mundo real. El @CustomScopeddebe referir a un encargo de Map<K, Bean>la aplicación de alguna alcance más amplio, que ha anulado Map#put()y / o Map#get()fin de tener un control de grano más fino sobre la creación de frijol y / o destruir.

El JSF @NoneScopedy el CDI @Dependentbásicamente viven tanto tiempo como una única evaluación EL en el bean. Imagine un formulario de inicio de sesión con dos campos de entrada que hacen referencia a una propiedad de bean y un botón de comando que hace referencia a una acción de bean, por lo tanto, con un total de tres expresiones EL, se crearán efectivamente tres instancias. Uno con el nombre de usuario establecido, otro con la contraseña establecida y otro en el que se invoca la acción. Normalmente desea usar este alcance solo en beans que deberían vivir tanto tiempo como el bean donde se está inyectando. Así que si una @NoneScopedo @Dependentse inyecta en una @SessionScoped, entonces se va a vivir siempre y cuando el @SessionScopedcafé en grano.

Ver también:


Alcance del flash

Como último, JSF también es compatible con el alcance de flash. Está respaldado por una cookie de vida corta que está asociada con una entrada de datos en el alcance de la sesión. Antes de la redirección, se establecerá una cookie en la respuesta HTTP con un valor que está asociado únicamente con la entrada de datos en el alcance de la sesión. Después de la redirección, se comprobará la presencia de la cookie de alcance flash y la entrada de datos asociada con la cookie se eliminará del alcance de la sesión y se colocará en el alcance de la solicitud de la solicitud redirigida. Finalmente, la cookie se eliminará de la respuesta HTTP. De esta forma, la solicitud redirigida tiene acceso a los datos de ámbito de solicitud que se prepararon en la solicitud inicial.

En realidad, esto no está disponible como un ámbito de bean administrado, es decir, no existe tal cosa @FlashScoped. El alcance flash solo está disponible como un mapa a través ExternalContext#getFlash()de beans gestionados y #{flash}en EL.

Ver también:

BalusC
fuente
44
Creo que una referencia a su respuesta a la pregunta " ¿Cómo y cuándo se destruye un bean de alcance de vista en JSF? " Es relevante aquí.
Lii
3
@Cold: es un viejo alcance CDI y en JSF 2.2 sustituido por @FlowScoped(no es necesario iniciarlo / detenerlo manualmente).
BalusC
1
Y DeltaSpike también tiene ViewAccesscopedyWindowScoped
Kukeltje
@BalusC, creo que hay un problema, con ViewScopedbean en MyFaces 2.2. Actualmente estoy enfrentando un problema con ViewScopedbean y Ajax, que he publicado aquí . En MyFaces JIRA, también hay una discusión sobre este tema.
Tapas Bose
CDI define cuatro ámbitos incorporados: @RequestScoped @SessionScoped @ApplicationScoped @ConversationScoped ¿por qué los ámbitos que describe son diferentes?
Hosein Aqajani
122

Desde JSF 2.3, todos los ámbitos de bean definidos en el paquete del javax.faces.beanpaquete han quedado en desuso para alinear los ámbitos con CDI. Además, solo son aplicables si su bean usa @ManagedBeananotaciones. Si está utilizando versiones JSF inferiores a la 2.3, consulte la respuesta heredada al final.


Desde JSF 2.3, aquí hay ámbitos que se pueden usar en JSF Backing Beans:

1@javax.enterprise.context.ApplicationScoped .: El ámbito de aplicación persiste durante toda la duración de la aplicación web. Ese alcance se comparte entre todas las solicitudes y todas las sesiones. Esto es útil cuando tiene datos para toda la aplicación.

2@javax.enterprise.context.SessionScoped .: El alcance de la sesión persiste desde el momento en que se establece una sesión hasta su finalización. El contexto de la sesión se comparte entre todas las solicitudes que se producen en la misma sesión HTTP. Esto es útil cuando no va a guardar datos para un cliente específico para una sesión en particular.

3@javax.enterprise.context.ConversationScoped .: El alcance de la conversación persiste como registro mientras vive el bean. El alcance proporciona 2 métodos: Conversation.begin()y Conversation.end(). Estos métodos deben llamarse explícitamente, ya sea para iniciar o finalizar la vida de un bean.

4@javax.enterprise.context.RequestScoped .: El alcance de la solicitud es de corta duración. Comienza cuando se envía una solicitud HTTP y finaliza después de que la respuesta se devuelve al cliente. Si coloca un bean administrado en el alcance de la solicitud, se crea una nueva instancia con cada solicitud. Vale la pena considerar el alcance de la solicitud si le preocupa el costo del almacenamiento del alcance de la sesión.

5@javax.faces.flow.FlowScoped .: El alcance del flujo persiste mientras viva el flujo. Un flujo puede definirse como un conjunto de páginas (o vistas) que definen una unidad de trabajo. El ámbito de flujo estado ha estado activo mientras el usuario navegue en el flujo.

6@javax.faces.view.ViewScoped .: Un bean en el alcance de la vista persiste mientras se vuelve a mostrar la misma página JSF. Tan pronto como el usuario navega a una página diferente, el bean queda fuera de alcance.


La siguiente respuesta heredada se aplica a la versión JSF anterior a la 2.3

A partir de JSF 2.x hay 4 Bean Scopes:

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

Alcance de la sesión: el alcance de la sesión persiste desde el momento en que se establece una sesión hasta su finalización. Una sesión finaliza si la aplicación web invoca el método de invalidación en el objeto HttpSession, o si se agota el tiempo de espera.

RequestScope: el alcance de la solicitud es de corta duración. Comienza cuando se envía una solicitud HTTP y finaliza después de que la respuesta se devuelve al cliente. Si coloca un bean administrado en el alcance de la solicitud, se crea una nueva instancia con cada solicitud. Vale la pena considerar el alcance de la solicitud si le preocupa el costo del almacenamiento del alcance de la sesión.

ApplicationScope: el alcance de la aplicación persiste durante toda la duración de la aplicación web. Ese alcance se comparte entre todas las solicitudes y todas las sesiones. Coloca beans administrados en el ámbito de la aplicación si un solo bean se debe compartir entre todas las instancias de una aplicación web. El bean se construye cuando un usuario de la aplicación lo solicita por primera vez, y permanece activo hasta que la aplicación web se elimina del servidor de aplicaciones.

ViewScope: el alcance de la vista se agregó en JSF 2.0. Un bean en el alcance de la vista persiste mientras se vuelve a mostrar la misma página JSF. (La especificación JSF usa el término vista para una página JSF). Tan pronto como el usuario navega a una página diferente, el bean queda fuera de alcance.

Elija el alcance según sus requisitos.

Fuente: Core Java Server Faces 3rd Edition por David Geary y Cay Horstmann [Página no. 51 - 54] ingrese la descripción de la imagen aquí

Kishor Prakash
fuente
¿Podría aclarar qué quiere decir con "el método de invalidación en el objeto HttpSession": invalidate()método o método no válido?
Alexander Pozdneev
1
Un poco viejo y quizás tarde para responder, pero para aclararlo: FacesContext.getCurrentInstance().getExternalContext().invalidateSession();lo que quiere decir es que te invoquen en tu "bean de cierre de sesión".
Roland
1
se convirtió en una respuesta heredada, en este momento hay 8 ámbitos
Ewoks
@KishorPrakash: hace un tiempo hace 6 meses. ;-)
Kukeltje
@Kukeltje: Lo siento, estoy en eso.
Kishor Prakash