SeamFramework.orgCommunity Documentation

Capítulo 5. Ámbitos y contextos

5.1. Tipos de ámbito
5.2. Ámbitos incorporados
5.3. El ámbito de conversación
5.3.1. Demarcación de conversación
5.3.2. Propagación de conversación
5.3.3. Pausa de conversación
5.4. El seudo ámbito dependiente
5.4.1. La anotación @New

Hasta ahora, hemos visto algunos ejemplos de anotaciones de tipo ámbito. El ámbito de un Web Bean determina el ciclo de vida de instancias del Web Bean. El ámbito también determina qué clientes se refieren a qué instancias del Web Bean. Según la especificación de Web Beans, un ámbito determina:

  • Cuándo se crea una nueva instancia de un Web Bean con ese ámbito

  • Cuándo se destruye una instancia existente de cualquier Web Bean con ese ámbito

  • Qué referencias se refieren a una instancia de un Web Bean con ese ámbito

Por ejemplo, si tenemos una sesión con ámbito Web Bean, UsuarioActual, todos los Web Beans que son llamados en el contexto de la misma HttpSession verán la misma instancia del UsuarioActual. Dicha instancia se creará automáticamente la primera vez que se necesite un UsuarioActual en esa sesión, y se destruirá automáticamente al terminar la sesión.

Web Beans ofrece un modelo contextual extensible. Es posible definir nuevos ámbitos creando una nueva anotación de tipo de ámbito:

@Retention(RUNTIME)

@Target({TYPE, METHOD})
@ScopeType
public @interface ClusterScoped {}

Claro está que esa es la parte fácil. Para que este tipo de ámbito sea útil, necesitaremos también definir un objeto Contexto que implemente el ámbito. La implementación de un Contexto suele ser una tarea muy técnica, únicamente destinada a desarrollo de marco.

Podemos aplicar un tipo de anotación de ámbito a una clase de implementación de Web Bean para especificar el ámbito del Web Bean:

@ClusterScoped

public class SecondLevelCache { ... }

Por lo general, se utilizará uno de los ámbitos incorporados de Web Beans.

Web Beans define cuatro ámbitos incorporados:

Para una aplicación de red que utilice Web Beans:

Los ámbitos de petición y aplicación también están activos:

Si la aplicación trata de invocar un Web Bean con un ámbito que no tiene un contexto activo, el administrador de Web Bean produce una ContextNotActiveException de Web Bean en tiempo de ejecución.

Tres de los ámbitos incorporados deben ser extremadamente familiares a cualquier desarrollador de Java EE, por eso no perdamos tiempo en explicarlos aquí. No obstante, uno de los ámbitos es nuevo.

El ámbito de conversación de Web Beans es un poco parecido al ámbito de sesión tradicional en que mantiene el estado asociado con el usuario del sistema y abarca varias peticiones al servidor. Sin embargo, a diferencia del ámbito de sesión, el ámbito de conversación:

Una conversación representa una tarea, una unidad de trabajo desde el punto de vista del usuario. El contexto de conversación mantiene un estado asociado con lo que el usuario está actualmente trabajando. Si el usuario está trabajando en varias tareas al mismo tiempo, habrá múltiples conversaciones.

El contexto de conversación está activo durante cualquier petición de JSF. Sin embargo, la mayoría de las conversaciones se destruyen al final de la petición. Si una conversación debe mantener un estado a través de múltiples peticiones, debe ser explícitamente promovida a conversación-larga.

Web Beans ofrece un Web Bean incorporado para controlar el ciclo de vida de conversaciones en una aplicación JSF. Dicho Web Bean puede obtenerse por inyección:

@Current Conversation conversation;

Para iniciar la conversación asociada con la petición actual a una conversación larga, llame al método begin() desde el código de aplicación. Para programar que el actual contexto de conversación larga se destruya al final de la petición actual, llame a end().

En el ejemplo a continuación, un Web Bean de conversación en ámbito controla la conversación con la que está asociada.

@ConversationScoped @Stateful

public class OrderBuilder {
    private Order order;
    private @Current Conversation conversation;
    private @PersistenceContext(type=EXTENDED) EntityManager em;
    
    @Produces public Order getOrder() {
        return order;
    }
    public Order createOrder() {
        order = new Order();
        conversation.begin();
        return order;
    }
    
    public void addLineItem(Product product, int quantity) {
        order.add( new LineItem(product, quantity) );
    }
    public void saveOrder(Order order) {
        em.persist(order);
        conversation.end();
    }
    
    @Remove
    public void destroy() {}
    
}

Este Web Bean puede controlar su propio ciclo de vida mediante la API de Conversación. No obstante, algunos otros Web Beans tienen un ciclo de vida que depende totalmente de otro objeto.

Además de los cuatro ámbitos incorporados, Web Beans ofrece el ámbito seudo dependiente. Este es el ámbito para el Web Bean que no declare explícitamente un tipo de ámbito.

Por ejemplo, este Web Bean tiene el ámbito de tipo @Dependent:

public class Calculator { ... }

Cuando un punto de inyección de un Web Bean apunta a un Web Bean dependiente, una nueva instancia del Web Bean dependiente es creada cada vez que el primer Web Bean sea instanciado. Las instancias de Web Beans dependientes nunca se comparten entre Web Beans o puntos diferentes de inyección. Ellas son objetos dependientes de alguna otra instancia de Web Bean.

Las instancias dependientes de Web Bean se destruyen cuando la instancia de la que dependen es destruida.

Web Beans facilita la obtención de una instancia dependiente de una clase de Java o bean EJB, incluso si la clase o el bean EJB ya se declaró como Web Bean con algún otro tipo de ámbito.