• No se han encontrado resultados

Tema 5. Capa de lógica de aplicación en Java EE

N/A
N/A
Protected

Academic year: 2021

Share "Tema 5. Capa de lógica de aplicación en Java EE"

Copied!
24
0
0

Texto completo

(1)

Tema 5. Capa de l´

ogica de aplicaci´

on en

Java EE

DAGSS – Dise˜

no de Arquitecturas de Grandes Sistemas Software

4

o

Grado Ing. Inform´

atica

http://ccia.ei.uvigo.es/docencia/DAGSS

(2)

5.1 Enterprise JavaBeans, versi´

on 3.x

Componentes del lado del servidor que encapsulan la l´

ogica de la

aplicaci´

on y que son gestionados por el contenedor de EJBs

Cada Enterprise JavaBean encapsula parte de la l´

ogica de negocio

de la aplicaci´

on

Paquete

javax.ejb.*

: interfaces, anotaciones, excepciones, ...

Ventajas que aportan

Permiten la distribuci´

on de la l´

ogica entre distintas m´

aquinas

man-teniendo la transparencia

• Uso de directorios JNDI para nombrar y acceder a los componentes y recursos

Manejo de transacciones para controlar accesos concurrentes

asegu-rando la integridad de los datos

• Controladas por el contenedor de EJB

Simplifican el desarrollo de aplicaciones que atiendan una gran

varie-dad de clientes (clientes web o ”de escritorio” (

stand-alone

), cliente

locales o remotos, etc)

Dise˜

no orientado a componentes

reusabilidad y abstracci´

on

• El desarrollador se concentra en la l´ogica de negocio y utiliza los servicios proporcionados por el contenedor

Servicios b´

asicos a los que da soporte el contenedor EJB

1. Persistencia mediante JPA (

Java Persistence API

)

2. Invocaci´

on remota de m´

etodos mediante RMI/IIOP

3. Procesamiento de transacciones y control de la concurrencia

Por defecto cada invocaci´on de un m´etodo de un EJB forma parte de una transacci´on

4. Procesamiento de eventos/mesajes as´ıncronos

(API Java Message Service

[JMS])

5. Servicios de directorio:

JNDI (Java Naming and Directory Interface)

6. Seguridad: autenticaci´

on, control de acceso y privilegios, criptograf´ıa

(3)

7. Publicaci´

on de los m´

etodos de negocio de los EJBs como servicios

Web SOAP (JAX-WS) o REST (JAX-RS)

(4)

(a) Tipos de EJB

Message-Driven EJBs

(EJBs dirigidos por mensajes)

Permiten el procesamiento de mensajes (operaciones) de forma

as´ıncrona (recepci´

on y tratamiento de eventos JMS)

Act´

uan como

listeners

(escuchadores) de eventos JMS (

Java

Message Service

)

• Implementan el interfaz MessageListener

Se ”suscriben” a una cola (

queue

) quedando a la espera y se

activan cuando se recibe un mensaje dirigido a dicha cola

• Esos mensajes JMS pueden ser enviados por cualquier componente de una aplicaci´on Java EE (clientes, componentes Web, otros EJBs)

• Los ”clientes” de un Message-Driven EJB no invocan directamente sus m´etodos, simplemente env´ıan mensajes JMS

Session EJBs

(EJBs de sesi´

on)

Representan

procesos de negocio

(funcionalidades de la aplicaci´

on)

implementan un

interfaz de negocio

(

bussines interface

)

Gestionan la interacci´

on con los ”clientes” (objetos/procesos que

hacen uso del componente) y encapsulan el flujo y manipulaci´

on

de la informaci´

on en el servidor

• Proporcionan a los ”clientes” una ”fachada” de los servicios proporcionados por otros componentes disponibles en el servidor (patr´on de dise˜no Facade)

Ofrecen operaciones s´ıncronas (petici´

on-respuesta)

• Procesos de negocio ejecutados en respuesta a una solicitud del cliente

Contenedor de EJBs crea e inicializa sus instancias (inyect´

andoles

las referencias necesarias) y las asigna a los ”clientes” a medida

que estos los van requiriendo (

pool

de EJBs)

En un instante de tiempo dado, s´

olo un ”cliente” tiene acceso a

los m´

etodos de la instancia del EJB (control de concurrencia)

• Contenedor de EJBs garantiza que cada m´etodo del EJB se ejecuta dentro

de una transacci´on at´omica

Nota:Desde EJB 3.1 se permite declarar m´etodos as´ıncronos dentro de EJBs de sesi´on marc´andolos con la anotaci´on @Asyncronous

En el caso de que el m´etodo tenga valor de retorno T, el tipo del valor de retorno del m´etodo as´ıncrono ser´a Future<T>

public Future<EstadoPago> procesarPagoTarjeta(int cantidad, Tarjeta tarjeta){...}

(5)

(b) EJBs de sesi´

on

Tipos de EJB de sesi´

on:

en funci´

on la interacci´

on con el ”cliente”

(quien realiza las llamadas)

Stateful EJB: tienen un estado conversacional dependiente del cliente

• Cada llamada est´a condicionada por las anteriores (importa el orden)

• Los valores de sus atributos se mantienen entre las distintas invocaciones de un mismo ”cliente”

◦ Representan el estado de la interacci´on con un cliente espec´ıfico

• Cada instancia de un stateful EJB ”atiende” invocaciones de un ´unico ”cliente”

◦ En funci´on delestado conversacional el resultado de las operaciones realizadas podr´a variar

• Estado conversacional no es persistente (no se mantiene cuando el cliente ”libera” el EJB)

◦ Valores de atributos no premanentes: finalizada sesi´on el estado desaparece

◦ Por eficiencia el contenedor de EJBs puede decidir detener temporalmente la ejecuci´on un

stateful EJB, almacenando temporalmente su estado en disco para recuperarlo al volver a la ejecuci´on

• Ejemplo: objeto”carrito de la compra” en el cual se van a˜nadiendo productos

Stateless EJB: no almacenan datos de los ”clientes” que los invocan

• Cada llamada es independiente de las dem´as

• Para el ”cliente” todos los stateless EJB son id´enticos (e intercambiables)

◦ Estado de unstateless EJB no contiene informaci´on espec´ıfica de un cliente

no se garantiza que los valores de sus atributos se mantengan entre llamadas

◦ Stateless EJBs realizan tareas gen´ericas e id´enticas para todos los clientes

• Pueden implementar Servicios Web (anotaciones @WebServicey @WebMethod)

• Ejemplo: objeto”gestor de art´ıculos”: altas, bajas, modificaciones de art´ıculos

Singleton EJB: contenedor garantiza que existe una ´unica instancia del objeto, compartida por todos los ”clientes” del EJB (estado global compartido).

• Por defecto el acceso concurrente lo gestiona el contenedor, pero puede controlarse por c´odigo mediante anotaciones @Lock

• Uso t´ıpico: gesti´on de datos globales de la aplicaci´on (cach´es, etc)

Interfaces en EJB de sesi´

on

Interfaz de negocio

de un EJB define el tipo de acceso permitido a

sus clientes

(Define la visi´on del EJB que tiene el cliente)

Un EJB de de sesi´

on puede tener varios interfaces de negocio con

distintos tipos de acceso

Clientes remotos: pueden ejecutarse en m´aquinas virtuales (JVM) distintas a la del EJB que invocan

• Pueden ser: componentes web (servlet, JSP), clientes remotos u otros EJBs

• Para el cliente remoto la localizaci´on del EJB es transparente (s´olo necesita acceso al directorio JNDI)

(6)

(c) Definici´

on de EJBs de sesi´

on

(1) Definici´

on del interfaz de negocio

Interfaces de negocio

interfaces Java decorados con las

anota-ciones

@Remote

o

@Local

para indicar las restricciones de acceso

◦ El interfaz y todos los m´etodos definidos deben de ser public

◦ Mismas restriciones para tipos de par´ametros y valores de retorno que Java RMI

Si no se indica con una anotaci´

on en el interfaz o en el EJB se

asume todos los interfaces son locales por defecto

Ejemplos:

@Remote

public interface CarritoCompra {

public void inicializarCarrito(Cliente c);

public void anadirArticulo(Articulo a, int cant); public void eliminarArticulo(Articulo a);

public void vaciarCarrito(); };

@Local

public interface GestorClientes { public void alta(Cliente c); public void baja(Cliente c); public void actualizar(Cliente c; public cliente buscarDNI(String DNI); };

Nota:

Llamadas remotas son mucho m´

as costosas que locales

◦ En general se tiende a pasar par´ametros ”grandes” ⇒ reducir n´um. de

llamadas pasando mayor cantidad de informaci´on

(2) Implementaci´

on de EJBs de sesi´

on

Clases

de

implementaci´

on

marcadas

con

las

anotaciones

@Stateless

,

@Stateful

´

o

@Singleton

seg´

un del tipo de

bean

Se indican los interfaces de negocio implementados (

implements

)

@Stateless

public class GestorClientesBean implements GestorClientes { ... } @Stateful

public class CarritoCompraBean implements CarritoCompra { ... }

◦ Opcionalmente se puede asociar un nombre JDNI al EJB para su acceso (par´ametro mappedName="...." de ambas anotaciones)

@Stateless(mappedName="gestor_clientes") ... @Stateful(mappedName="carrito_compra") ...

Nota: si no se indica nada el contendor EJB asignar´a uno por defecto

◦ Opcionalmente se puede omitir la palabra clave implements explicitando el nombre y el tipo de acceso de los interfaces de negocio soportados mediante anotaciones.

@Stateless @Local(GestorClientes.class) ... @Stateful @Remote(CarritoCompra.class) ...

◦ En EJB 3.1 (incluido EJB lite), no se requiere definir interfaz para EJBs

con acceso local (no-inteface view), basta marcar la clase con la anotaci´on

(7)

Se pueden marcar m´

etodos con anotaciones especiales para

in-dicar que sean invocados por el contenedor EJBs en momentos

concretos del ciclo de vida del

bean

◦ @PostConstruct: una vez que el contenedor instancia el EJB y le inyecta dependencias (antes de recibir su primera invocaci´on)

◦ @PreDestroy: justo antes de eliminar definitivamente el EJB

◦ @PrePassitivate: (s´olostateful) justo antes almacenar el estado en disco temporalmente

◦ @PostPassitivate (s´olo stateful) justo de recuperar el estado almacenado en disco temporalmente

etodo anotado con

@Remove

puede ser invocado por clientes para

provocar eliminaci´

on de una instancia del EJB del contenedor

(3) Empaquetado y despliegue

Empaquetado de EJBs:

Creaci´

on de fichero JAR conteniendo:

◦ Bytecode (ficheros .class) de

  

clases de implemementaci´on de EJBs interfaces de negocio

otras clases auxiliares necesarias

Ficheros .class estructurados en paquetes (subdirectorios) seg´un corresponda

◦ Directorio META-INF conteniendo los ficheros de configuraci´on exigidos por el contenedor o/y otros que pudieran ser necesarios

descriptor de despliegue [ejb-jar.xml]

descriptor de persistencia JPA [persistence.xml]

MANIFEST.MF

otros: descriptor de despliegue espec´ıfico del contenedor (glassfish-ejb-jar.xml) ...

◦ Librer´ıas adicionales (ficheros JAR)

Despliegue de EJBs:

El fichero JAR resultante se puede

des-plegar directamente en el contenedor JEE o incluirlo como un

odudo EJB de una Aplicaci´

on JEE (paquetes

EAR

)

◦ Al ser deplegado un EJB en un contenedor se le asocia un nombre seg´un lo indicado en sus anotaciones o en su descriptor de despliegue

◦ Ese nombre se registra en el servidor de nombres del contendor EJB, accesible por JNDI.

◦ Una vez desplegado los clientes pueden acceder al EJB usando ese nombre e invocar sus m´etodos

(8)

(c) Acceso e invocaci´

on de EJBs de sesi´

on

Para utilizar m´

etodos de un EJB desplegado es necesario que el

cliente cuente con una referencia a un representante (

proxy

o

stub

)

del mismo

• proxy gestiona las invocaciones, bien locales o bien sobre RMI/IIOP

Opci´

on 1:

Inyecci´

on de dependencias por parte del contenedor JEE

Uso de la anotaci´

on

@EJB

acompa˜

nando al atributo donde se

mantendr´

a la referencia al EJB

◦ El tipo del atributo/referencia ser´a el nombre del interfaz de negocio que se desea invocar

◦ El contenedor usar´a el nombre por defecto del EJB (o el que se especifique en el par´ametro @EBJ(mappedName="...")) para consultar al servidor de nombres JNDI, inyectando en ese atributo la referencia encontrada

Inyecci´

on de referencias con

@EJB

olo es posible dentro de un

entorno de ejecuci´

on JEE

◦ Contenedor de servlets: es posible inyectar EJBs para invocarlos desde servlets, p´aginas JSP, Java beans o @ManagedBeans de JSF

◦ Contenedor de EJBs: posible inyectar EJBs para invocarlos desde otros EJBs

◦ Contenedor de clientes JEE: clientes Java stand-alone ejecut´andose en el contexto de un contenedor de clientes JEE pueden obtener e invocar EJBs

Es necesario disponer de las API de JEE 6 para inyectar estas dependencias

Ejemplo: appclient en GlassFish

Importante:Los contenedores de clientes JEE s´olo pueden inyectar EJBs sobre atributos de tipo static de la clase principal donde se incluya el m´etodo main()

Ejemplo:

public class ClaseLlamadora {

@EJB // puede especificarse un nombre de EJB con mappedName (opcional) private CarritoCompra carrito;

...

public void metodoLlamador(String args[]) { ... carrito.inicializar(...); carrito.anadir(...); ... } }

(9)

Opci´

on 2:

Consulta JDNI empleando el nombre asignado al EJB

Siempre es posible consultar el servicio JNDI presente en todos

los servidores aplicaciones JEE

◦ Se usa el API de JNDI → paquete javax.naming.*

◦ Interfaz InitialContext, m´etodos lookup(...)

Se obtiene una referencia a un EJB a partir del nombre asignado

(en la anotaci´

on, en el descriptor de despliegue o del nombre por

defecto asignado por el contenedor)

◦ Este era el modo en que se hac´ıa en las versiones de EJB 2.x y anteriores

◦ Antes de JEE 6: el nombre por defecto con el que se registraban los EJBs no estaba estandarizado

cada servidor de aplicaciones organizaba el directorio de nombres JNDI de forma distinta

◦ JEE 6 especifica formato estandar para nombres por defecto de los EJBs

java:global[/<app-name>]/<module-name>/<bean-name>[!<fully-qualified-interface-name>]

Consultas JNDI desde clientes

stand-alone

◦ Es necesario configurar las properties de la m´aquina virtual cliente para indicar la direcci´on y el puerto de escucha del servicio JNDI del contenedor donde est´a desplegado el EJB (dependiente de cada contenedor)

Nota: con GlassFish las propiedades a especificar son:

org.omg.CORBA.ORBInitialHost →IP/nombre servidor aplicaciones JEE

org.omg.CORBA.ORBInitialPort →3700

Pueden indicarse como par´ametros de la JVM al arrancar (-Dparametro=valor) o con System.setProperty(’’parametro’’, valor);

◦ Con esa informaci´on ser´a posible obtener un InitialContex donde buscar [lookup()] el nombre del EJB deseado

Ejemplo:

import javax.naming.InitialContext; public class EjemploCliente {

public static void main(String args[]) { ...

InitialContext ic = new InitialContext(); CarritoCompra carrito = (CarritoCompra) ic.lookup("java:global/EjemploTiendaWeb/"+ "EjemploTiendaWeb-ejb/CarritoCompraBean"); carrito.inicializar(...); carrito.anadir(...); ... }

(10)

Transacciones en EJBs

Contenedor de EJBs ofrece por defecto gesti´

on de transacciones sobre

etodos de EJBs

(container-managed transactions [CMT])

EJB tambi´

en pueden gestionar desde c´

odigo sus propias transacciones

(

bean managed transactions [BMT]

)

Mediante el API JTA (Jave Transaction API) [objetosjavax.transaction.UserTransaction]

UserTransaction provee los m´etodos begin() , commit() y rollback()

EJBs con transacciones BMT se ”marcan” con la anotaci´on

@@TransactionManagement(TransactionManagementType.BEAN)

Se puede especificar que el contenedor de EJBs inyecte una instancia de

UserTransaction mediante la anotaci´on @Resource @Resource

UserTransaction utx;

Tambi´en se pueden obtener con un consulta JNDI

En la gesti´

on de transacciones se busca garantizar las propiedades ACID:

Atomicidad (Atomicity): una transacci´on est´a compuesta de 1 o m´as unidades de trabajo

• o se ejecutan TODAS ellas [commit]

• o no se ejecuta NINGUNA [rollback], si ocurre alg´un error (exception) inesperado no recuperable

Consistencia (Consistence): al finalizar la transacci´on (´exito [commit] ´o fracaso [rollback]) los datos se dejan en un estado consistente

aIslamiento (Isolation): el estado intermedio de la transacci´on no es visible a los dem´as compo-nentes de la aplicaci´on (u a otras aplicaciones)

Durabilidad (Durability): una vez la transacci´on se completa con ´extio [commit] los cambios realizados sobre los datos son visibles al resto de aplicaciones

Por defecto todos los m´

etodos de los EJBs que usan CBT se ejecutar´

an

dentro de una transacci´

on (no es necesaria configuraci´

on expl´ıcita)

EJBs se consideran anotados por defecto con@TransactionManagement(TransactionManagementType.CONTAINER)

Pueden especificarse caracter´ısticas espec´ıficas en la gesti´on de transacciones a nivel de EJB o de m´etodo [anotaci´on @TransactionAttribute(TransactionAttributeType.XXX)]

(11)

• Si el ”cliente” del EJB ya ha iniciado una transacci´on, el m´etodo del EJB se ejecuta formando parte de ella.

• En otro caso, se inicia una transacci´on nueva para el m´etodo del EJB.

(el m´etodo del EJB se ejecuta siempre dentro de una transacci´on, propia o heredada) TransactionAttributeType.REQUIRES NEW

• Se inicia siempre una nueva transacci´on para el EJB.

• Si el ”cliente” ya hab´ıa iniciado una transacci´on, esta se suspende y se reanuda cuando termine el m´etodo del EJB.

(el m´etodo del EJB se ejecuta siempre dentro de una transacci´on propia) TransactionAttributeType.SUPPORTS

• Si el ”cliente” ha iniciado una transacci´on, el m´etodo del EJB se ejecuta dentro de ella.

• En otro caso, se ejecuta el m´etodo del EJB sin iniciar una transacci´on nueva. (se mantiene el estado transaccional del ”cliente”)

TransactionAttributeType.MANDATORY:

• Si el ”cliente” no ha iniciado una transacci´on, se lanza una excepci´on y se aborta la ejecuci´on del m´etodo del EJB.

• En otro caso, se utiliza la transacci´on iniciada por el ”cliente”.

(el m´etodo del EJB se ejecuta siempre dentro de una transacci´on proporcionada por el ”cliente”) TransactionAttributeType.NOT SUPPORTED

• Si el ”cliente” ha iniciado una transacci´on, esta se suspende, se ejecuta el m´etodo del EJB sin iniciar una transacci´on nueva y se reanuda la transacci´on del cliente.

(el m´etodo del EJB se ejecuta fuera de cualquier transacci´on) TransactionAttributeType.NEVER:

• Si el ”cliente” ha iniciado una transacci´on, se lanza una excepci´on y esta se suspende y no se ejecuta el m´etodo.

(12)

5.2 CDI: Context and Dependece Injection

Framework de inyecci´

on de dependencias y gesti´

on de objetos, disponible

desde Java EE 6.

Simplifica el desarrollo de componentes Java EE haciendo uso del principio IoC Inversion of Control

Servicios ofrecidos por CDI

1.

Inyecci´

on de dependencias: inyecci´

on de referencias a objetos

”fuertemente tipada”

Favorece un bajo acoplamiento

• simplifica plantear un dise˜no donde se depende de abstracciones (interfaces) en lugar de depende de implementaciones concretas

• CDI ”carga” con la responsabilidad de la creaci´on de los objetos

• no es necesario especificar las clases concretas a utilizar ni sus respectivas dependencias, CDI crear´a los objetos ”correctos” e inyectar´a esas referencias Posibilidad de ”configurar” la inyecci´on concreta en tiempo de despliegue (descriptor beans.xml)

2. Gesti´

on de

contextos: ciclo de vida de los objetos CDI est´

a vinculado

a contextos (

scopes

)

3. Gesti´

on del

ciclo de vida

de los objetos CDI (

beans CDI

): uso de

interceptores de llamadas a m´

etodos, definici´

on de decoradores y

gesti´

on de eventos

4.

Nombrado

de los

beans

: permite el acceso a los

beans

CDI desde

el

Expression Language

(EL) de JSF y JSP

(simplifica la integraci´on de la capa web y de la capa de l´ogica de aplicaci´on)

(13)

Beans CDI: un

bean

CDI puede ser casi cualquier objeto Java

No exige implementar interfaces concretos o heredar de determinadas clases : POJOs [plain old Java objects]

Puede ser accedido desde objetos ”cliente” v´ıa inyecci´on de dependencias (@Inject) o mediante un nombre desde el EL de JSF y JSP.

Componentes Java susceptibles de ser gestionados por CDI deben verificar: 1. no son una clase interna no est´atica

2. son una clase concreta o est´a anotada con @Decorator

3. tienen un constructor sin par´ametros o uno de sus constructores est´a anotado con @Inject

A un bean CDI puede vincul´arsele:

1. un contexto (scope) [@ApplicationScoped, @SessionScoped, @RequestScoped, ...] 2. un nombre EL [Named]

3. un conjunto de cualificadores [@Qualifier] que delimitan el tipo de cliente que podr´a inyectarlos

4. un conjunto de interceptores de m´etodos [@ArroundInvoke, @ArroundConstructor, @Interceptors]

5. puntos de gesti´on del ciclo de vida [@PostConstruct, @PreDestroy] 6. un conjunto de decoradores [@Decorator, @Delegate]

7. un conjunto de ”observadores” de eventos [Event<T>, @Observes]

Por defecto, se habilita CDI incluyendo un descriptor de despliegue beans.xml vac´ıo con la opci´onbean-discovery-mode="annotated"en los directorios de configuraci´on de la aplicaci´on (WEB-INF en aplicaciones web, META-INF en el resto de casos)

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="annotated"> </beans>

Framework CDI considera susceptibles de ser tipos v´alidos para los beans CDI todos los interfaces, clases abstractas, clases concretas, arrays y tipos b´asicos incluidos en la aplicaci´on, excepto los paquetes o tipos marcados con la anotaci´on

(14)

(a) Inyecci´

on de dependencias

Inyecci´

on de dependencias (DI :

dependence injection

) es un principio

de dise˜

no que desacopla la creaci´

on de objetos dependientes

la responsabilidad de crear los objetos y obtener las dependencias

necesarias pasa al contenedor de DI

(ejemplos: Spring, Google Guice, CDI)

en

Java

EE,

DI

presente

en

distintas

especificaciones:

@ManagedBeans

en JSF,

@EJB

,

@PersistenceContext

en EJBs,

inyecci´

on de recursos con

@Resource

(CDI unifica todas esas especifica-ciones)

Anotaci´

on

@Inject

Define en el objeto ”cliente”

(quien recibe la referencia de la dependencia inyectada)

un punto de inyecci´

on de una referencia a un bean CDI del

tipo especificado

(con frecuencia un nombre de interfaz Java)

Puede estar acompa˜

nado de uno o m´

as cualificadores

• usados en el caso de tipos de objetos CDI con varias implementaciones para delimitar la que finalmente ser´a inyectada

Puede especificarse un punto de inyecci´

on:

• en el propio atributo de la clase del bean CDI donde se inyectar´a la dependencia @Inject TipoBean atributo;

• en el m´etodo set() de ese atributo

@Inject void setAtributo(TipoBean atributo) { this.atributo = atributo;

}

• en un constructor

@Inject public ClaseBean(TipoAtributo atributo) { this.atributo = atributo;

(15)

Cualificadores

Por defecto CDI asume que existe una ´

unica implementaci´

on del tipo de

bean especificado por

@Inject

.

En caso de que s´

olo exista una implementaci´

on se inyecta la

corres-pondiente referencia

(creando e inicializando el bean CDI si es necesario)

• Por defecto todos los beans CDI cuantan con el cualificador Default

• La anotaci´on @Inject impl´ıcitamente

En caso de que existan m´

as implementaciones los cualificadores

(

@Qualifier

) permiten seleccionar cu´

al inyectar en cada caso

Las distintas implementaciones de un tipo CDI pueden estar

vin-culadas con anotaciones que ”hereden” de la anotaci´

on

Qualifier

(pueden vincularse a una clase varios cualificadores y ”exigirse” varios cualificadores en los @Inject)

@Qualifier

@Retention(RUNTIME)

@Target({FIELD, TYPE, METHOD}) public @interface Calificador1 { }

@Qualifier

@Retention(RUNTIME)

@Target({FIELD, TYPE, METHOD}) public @interface Calificador2 {

int parametro(); Tipo tipo(); }

public enum Tipo {A,B,C} public interface TipoBean; @Default

public class Implementacion1 implements TipoBean {...} @Calificador1

public class Implementacion2 implements TipoBean {...} @Calificador2(parametro=25, tio=Tipo.A)

(16)

public class ClienteBasico { ...

@Inject @Calificador1 TipoBean inyectado; ...

}

public class ClienteMejorado { ...

@Inject @Calificador2(parametro=25) TipoBean inyectado; ...

}

Si existen varias implementaciones, una de ellas debe estar marcada

con el cualificador

@Default

(si no es as´ı se genera una excepci´on)

• Por defecto todos los beans CDI que no incluyan un cualificador se anotan con el cualificador Default

• Si no se especifican cualificadores acompa˜nando a una anotaci´on @Inject, impl´ıcitamente se ”exige” Default

En el fichero

beans.xml

se puede modificar en tiempo de despliegue

el comportamiento por defecto, seleccionando un cualificador por

defecto de entre los marcados con

@Alternative

@Alternative @Default

public class Implementacion1 implements TipoBean {...} @Alternative @Calificador1

public class Implementacion2 implements TipoBean {...} ... <beans ...> <alternatives> <class>paquete.Implementacion2</class> </alternatives> </beans>

Por defecto las alternativas est´

an deshabilitadas, deben indicarse

expl´ıcitamente en

beans.xml

(17)

Productores

(anotaci´

on

@Produces

)

Usando la anotaci´

on

@Produces

es posible especificar que el origen de

una dependencia a inyectar sea el resultado de la invocaci´

on de un

etodo en lugar de ser un objeto de una clase determinada

(tambi´en es posible vincular @Produces a los atributos de una clase)

El m´etodo anotado con @Produces podr´a ir acompa˜nado de los cualificadores que correspondan.

En caso de que no exista una clase adecuada para la inyecci´on (o se haya especificado as´ı en beans.xml), el contenedor CDI se encargar´a de buscar un m´etodo adecuado para la inyecci´on entre los paquetes y clases de la aplicaci´on. Si lo encuentra, CDI lo invocar´a (creando una instancia si es necesario) e inyectar´a su valor de retorno en el punto/s de inyecci´on marcado por @Inject

La anotaci´on @Produces permite inyectar arrays y tipos b´asicos

Cuando existen cualificadores y alternativas los m´etodos @Produces funcionan como una especie de m´etodos factor´ıa ”tipado”, gobernado por los cualificadores, el beans.xml y la propia l´ogica del m´etodo.

En los casos en que la l´ogica del m´etodo @Produces requiera informaci´on sobre el contexto donde se va a inyectar su resultado puede incluir como par´ametro adicional un objeto InjectionPoint con informaci´on del ”cliente” CDI.

public class Productor {

@Produces @Calificador2(parametro=25) TipoBean productor1() { TipoBean instancia;

...

return instancia; }

@Produces @Calificador1 TipoBean productor1(InjectionPoint ip) { TipoBean instancia;

...

String claseReceptora = ip.getMember().getDeclaringClass().getName(); ...

return instancia; }

(18)

(b) Contextos (scopes) en CDI

Los beans CDI ”viven” en un contexto (alcance) gestionado por el

contendor CDI

Contenedor crea y maneja los beans dentro de cada contexto,

des-truy´

endolos al finalizar el contexto

Contenedor garantiza el mantenimiento del estado del bean dentro

del contexto

• Los ”clientes” donde se inyecta un bean CDI interact´uan siempre con el mismo objeto mientras el correspondiente contexto est´e activo

• Contenedor garantiza que desde el punto de vista de los clientes y dentro de un contexto dado existe una ´unica instancia de cada tipo de bean inyectado (CDI ofrece un especie singleton contextual)

Contexto de aplicaci´

on

@ApplicationScoped

Se prolonga durante la vida de la aplicaci´

on

Los beans CDI se crea en el momento en que arranca la aplicaci´

on y

se destruye al finalizar

Existe una ´

unica instancia de los beans compartida por todos los

”clientes”

Usado para funciones complementarias, cach´

es, etc

Puede presentar problemas de concurrencia

Contexto de sesi´

on

@SessionScoped

Se prolonga durante el conjunto de peticiones HTTP que se

corres-ponden con una sesi´

on de usuario

Vinculado al objeto

HttpSession

de la capa web

Los beans CDI se crean en su primer uso por parte del usuario

y se destruyen al finalizar la sesi´

on

(bien por una invocaci´on al m´etodo

invalidate() o por agotamiento de time-out de sesi´on)

Almacenan datos necesarios durante la sesi´

on de usuario

(credenciales de acceso, selecciones y preferencias, etc)

(19)

Contexto de petici´

on

@RequestScoped

Vinculado a una petici´

on HTTP concreta

Vinculado al objeto

HttpServletRequest

de la capa web

Los beans CDI se crean al recibir la petici´

on y se destruyen con el

env´ıo de su respuesta

Mantienen datos que s´

olo son necesarios para la petici´

on actual

Es el m´

as utilizado

(la anotaci´on @Model combina las anotaciones

@RequestScoped y @Named)

Contexto de conversaci´

on

@ConversationScoped

Contexto de duraci´

on variable, definida por la l´

ogica del bean

Todos los beans

@ConversationScoped

deben de inyectar un objeto

Conversation

a trav´

es del cu´

al se controla el contexto.

Existe desde que se invoca el m´

etodo

begin()

del objeto

Conversation

(normalmente en un m´etodo @PostContruct)

hasta la

in-vocaci´

on del m´

etodo

end()

Utilizado para gestionar datos que se mantienen entre invocaciones

sucesivas del cliente, pero con un alcance menor que la sesi´

on, en el

caso de aplicaciones web

Contexto dependiente

@Dependent

Contexto por defecto

El bean CDI ”’hereda” el contexto en el cu´

al se encontraba el

”cliente” al que fue inyectado

(20)

(c) Ciclo de vida de beans en CDI

El contenedor CDI gestiona el ciclo de vida de los beans.

En la creaci´

on del bean, CDI se encarga (por este orden) de:

1. Crear el objeto invocando a su constructor vac´ıo o al etiquetado con @Inyect

2. Realizar la inyecci´on de las dependencias requeridas por las anotaciones

@Inyect del beanName

3. Invocar a los m´etodos anotados con @PostConstruct

En la destruci´

on del bean, CDI invoca a los m´

etodos anotados con

@PreDestroy

justo antes de eliminar el bean de la JVM.

Opcionalmente, CDI puede invocar a los interceptores de los m´

etodos

anotados con

@ArroundInvoke

o

@ArroundContruct

Interceptores

Los interceptores CDI ofrecen funcionalidades basadas en los principios

de la programaci´

on orienta a aspectos

(AOP: Aspect Oriented Programming)

Suelen utilizarse para implementar funcionalidades que son comunes a varios componentes de la aplicaci´on (loging, transacciones, controles de seguridad, etc) Ofrecen un forma limita y muy espec´ıfica del patr´on Cadena de responsabilidad

(21)

1. Interceptores ”de clase”

En el propio bean se puede a˜nadir un interceptor propio marcando un m´etodo del bean con @ArroundInvoke o @ArroundsContruct

Ese m´etodo recibir´a un objeto InvocationContext con el cu´al acceder a infor-maci´on del m´etodo invocado

Mediante el m´etodo proceed() se indica que puede continuar su ejecuci´on public class ClienteService {

@Inject private EntityManager em; @Inject private Logger logger;

public void crearCliente (Cliente cliente) { em.persist(cliente);

} ...

@AroundInvoke private Object logMethod(InvocationContext ic) throws Exception { Logger.log("Entrando en clase "+ic.getTarget().toString()+

" con metodo "+ic.getMethod().getName()); try {

return ic.proceed(); } finally {

Logger.log("Saliendo de clase "+ic.getTarget().toString()+ " con metodo "+ic.getMethod().getName());

} } }

(22)

2. Interceptores generales

Lo m´as habitual es definir interceptores gen´ericos que podr´an emplearse en varios beans CDI

• marcando la clase que implementa los interceptores con@Interceptor

• definiendo una nueva anotaci´on (derivada de @InterceptorBinding) con la que vincular esa clase interceptora a los beans implicados

public class UsuarioService { private @Inject EntityManager em; @Transactional public almacenarUsuario(Usuario u) { em.persist(u); } } @Retention(RetentionPolicy.RUNTIME)

@Target( { ElementType.TYPE, ElementType.METHOD }) @InterceptorBinding

public @interface Transactional {}

@Interceptor @Transactional

public class TransactionalInterceptor { private @Inject EntityManager em; @AroundInvoke

public Object invoke(InvocationContext context) throws Exception{ EntityTransaction t =em.getTransaction(); try { if(!t.isActive()) { t.begin(); } return context.proceed(); } catch(Exception e) { t.rollback(); } finally {

if(t != null && t.isActive()) { t.commit();

} } } }

En ambos casos, para ser activados las clases que implementan los interceptores de-ber´an ser declaradas en el ficherobeans.xmldentro de etiquetas<interceptors>

(23)

(d) Decoradores y eventos

CDI incluye soporte a la implementaci´

on del

patr´

on Decorador

Decoradores similares en funcionamiento a los Interceptores (ampl´ıan las funciona-lidades de un objeto gestionado)

A diferencia de los Interceptores los Decoradores ”conocen” el inter-faz/comportamiento de la clase decorada

public interface TipoBasico { ... Metodos interfaz ... }

@Decorator

public class MiDecorador implements TipoBasico { @Inject @Delegate

private TipoBasico delegado; ... Metodos interfaz ... }

public class MiClase implements TipoBasico { ... Metodos interfaz ... } <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" version="1.1" bean-discovery-mode="all"> <decorators>

(24)

CDI incluye soporte a la implementaci´

on del

patr´

on Observer

Permite vincular comportamiento a acciones/eventos que ocurran sobre los objetos gestionados

public class BookService { @Inject

private NumberGenerator numberGenerator; @Inject

-> private Event<Book> bookAddedEvent;

public Book createBook(String title, Float price, String description) { Book book = new Book(title, price, description);

book.setIsbn(numberGenerator.generateNumber()); -> bookAddedEvent.fire(book);

return book; }

}

public class InventoryService { @Inject

private Logger logger;

List<Book> inventory = new ArrayList<>(); -> public void addBook(@Observes Book book) {

logger.info("Adding book " + book.getTitle() + " to inventory"); inventory.add(book);

} }

Referencias

Documento similar

En estos últimos años, he tenido el privilegio, durante varias prolongadas visitas al extranjero, de hacer investigaciones sobre el teatro, y muchas veces he tenido la ocasión

que hasta que llegue el tiempo en que su regia planta ; | pise el hispano suelo... que hasta que el

Para ello, trabajaremos con una colección de cartas redactadas desde allí, impresa en Évora en 1598 y otros documentos jesuitas: el Sumario de las cosas de Japón (1583),

En junio de 1980, el Departamento de Literatura Española de la Universi- dad de Sevilla, tras consultar con diversos estudiosos del poeta, decidió propo- ner al Claustro de la

Entre nosotros anda un escritor de cosas de filología, paisano de Costa, que no deja de tener ingenio y garbo; pero cuyas obras tienen de todo menos de ciencia, y aun

El contar con el financiamiento institucional a través de las cátedras ha significado para los grupos de profesores, el poder centrarse en estudios sobre áreas de interés

Fuente de emisión secundaria que afecta a la estación: Combustión en sector residencial y comercial Distancia a la primera vía de tráfico: 3 metros (15 m de ancho)..

La campaña ha consistido en la revisión del etiquetado e instrucciones de uso de todos los ter- mómetros digitales comunicados, así como de la documentación técnica adicional de