You are on page 1of 70

EJB 3

Que es un EJB?

Enterprise Java Bean Componente ejecutado en el lado del servidor que encapsula la logica de negocio de la aplicacion. Distribuibles por varios servidores. Abstrae de problemas generales (concurrencia, transacciones, eventos, persistencia, seguridad, etc).

Que es un EJB?

POJOs (Plain Old Java Objects) Implementan los interfaces cuyas logicas quieran servir.

OJO! Ya no tienen que extender de javax.ejb.EJBObject o javax.ejb.EJBHome (como se hacia EJB 2.0)

El contenedor de beans manejara su ciclo de vida

Tipos de EJB

Beans de entidad Beans de sesion (Session Beans) Beans de mensaje (Message Driven Beans o MDB)

Entidades

Beans persistentes Implementado mediante JPA

Ya se ha visto!

Beans de sesion

Implementan las logicas de negocio de la aplicacin Diferentes accesos:


Local Remoto Stateless ( request ) Stateful ( session ) Singleton ( application )

Diferentes ambitos:

OJO! Lo de los ambitos es solo una comparacion!

Acceso local

Declaramos un interfaz como local (@Local) El EJB que implemente dicho interfaz SOLO sera accesible desde la misma maquina virtual. Ventaja: Acceso rapido al EJB. Desventaja: no se puede acceder a el desde otra maquina.

Acceso remoto

Declaramos un interfaz como remoto (@Remote) El EJB que implemente dicho interfaz sera accesible desde la misma maquina virtual Y desde otras maquinas virtuales, aunque corran en otra maquina fisica diferente. Ventaja: Acceso remoto (RMI). Una aplicacin en un servidor puede acceder a un EJB remoto que este contenido en un otro servidor. Desventaja: lentitud. Overhead. Retardo en la red.

Beans stateless

POJOs con la anotacion @stateless Beans que implementan logicas sin estado (las logicas no pueden guardar informacion proveniente de invocaciones anteriores). No se garantiza que los contenidos de las variables del bean se conserve entre llamada y llamada. Se pueden ejecutar las logicas concurrentemente.

Beans stateless

Se utilizan cuando:

El EJB no contiene/guarda informacion especifica del cliente que lo ha invocado

Sin embargo, si que se le puede pasar informacion especifica del cliente EN EL MOMENTO DE LA INVOCACION.

Ejecuta logicas genericas

Ciclo de vida de un bean stateless

El bean no existe

El contenedor instancia el bean Se inyectan las dependencias Se llama al metodo callback PostConstruct Se ejecuta el metodo invocado. Se guarda el bean en bean pool, esperando una nueva invocacion por parte de cualquier cliente. En algun momento, el contenedor decide destruir el bean que esta en el pool.

El bean esta listo


Ciclo de vida de un bean stateless

El bean va a ser destruido


Se llama al metodo callback PreDestroy Se elimina el bean

Ciclo de vida de un bean stateless

DEMOSTRACION

ESTO SUENA A CHINO!!!

Creacion de proyecto JSF


Proceso ya visto anteriormente. Llamamos FacebullJSF al proyecto

Creacion de proyecto EJB

Nuevo -> Proyecto -> EJB project

Creacion de proyecto EJB

Nombre del proyecto: FacebullEJB

modificar

Creacion de proyecto EJB

Activamos JPA (ya visto)

Creacion de proyecto EJB

Creacion de proyecto EJB

Creacion de proyecto EJB

Configuramos la librera JPA y la conexin (ya visto)

Creacion de Enterprise Application

Nuevo Proyecto -> Enterprise Application Project

Creacion de Enterprise Application

Lo llamamos Facebull

Creacion de Enterprise Application

Incluimos los dos proyectos ya creados

Creacion de proyecto EJB

Al final tendremos tres proyectos:

FacebullEJB:

Back-end de la aplicacion Contiene las logicas de negocio, las entidades y el modelo Front-end de la aplicacion. Se invocaran las logicas de negocio de los EJB desde los managed beans. Proyecto EAR que despliega las dos anteriores.

FacebullJSF:

Facebull

Creacion de EJB stateless

En nuestro proyecto FacebullEJB creamos un nuevo EJB de sesion

Creacion de EJB stateless

Paquete.Nombre: servicios.Seguridad

Creacion de EJB stateless

Creacion de EJB stateless

Paquete.Nombre: servicios.Seguridad

Creacion de EJB stateless

Se habran creado 3 ficheros

SeguridadRemote.java:

Define las logicas invocables remotamente Define las logicas invocables localmente Implementa las logicas anteriores

SeguridadLocal.java:

Seguridad.java

Nota: Si se necesita que una misma logica sea invocable tanto local como remotamente, se define igual en ambos interfaces (pero se implementa una unica vez)

SeguridadRemote.java

package servicios; import javax.ejb.Remote; @Remote public interface SeguridadRemote { boolean autentificar(String usuario, String password); }

SeguridadLocal.java

package servicios; import javax.ejb.Remote; @Local public interface SeguridadLocal { boolean autentificar(String usuario, String password); }

Seguridad.java
package servicios; import javax.ejb.LocalBean; import javax.ejb.Stateless; @Stateless @LocalBean public class Seguridad implements SeguridadRemote, SeguridadLocal {

System.out.println("Autentificando " + usuario + "/" + password);


public boolean autentificar(String usuario, String password) { if ((usuario != null) && (password != null) && (usuario.equals("Administrador")) && (password.equals("1234"))) { return true; } else { return false; }

} ...

Seguridad.java

... @PostConstruct public void inicializar() { System.out.println("Inicializando"); } @PreDestroy public void finalizar() { System.out.println("Finalizando"); } }

TERMINAR EJEMPLO

Beans stateful

POJOs con la anotacion @stateful Beans que implementan logicas con estado (las logicas pueden guardar informacion proveniente de invocaciones anteriores). El contenedor garantiza que mientras dure la sesion del cliente o se elimine el bean, los contenidos de las variables del bean se conservaran.

Beans stateful

Se utilizan cuando:

El EJB guarda informacion especifica del cliente que lo ha invocado.

Ciclo de vida de un bean stateful

El bean no existe

El contenedor instancia el bean Se inyectan las dependencias Se llama al metodo callback @PostConstruct Se ejecuta el metodo invocado. Se guarda el bean, esperando una nueva invocacion por parte del MISMO cliente. Si pasa cierto tiempo sin ser usado, el contenedor puede decidir pasivar el bean(mandarlo a la memoria secundaria). Se ejecuta la callback @Prepassivate.

El bean esta listo


Ciclo de vida de un bean stateful

Si se termina la sesion del usuario o si el usuario ejecuta el metodo anotado con @remove, se destruye el bean. Se llama al metodo callback PreDestroy Se elimina el bean Se llama al metodo callback @PrePassivate Cuando el bean va a ser utilizado de nuevo, se recupera de la memoria secundaria y se llama a la callback @PostActivate

El bean va a ser destruido


El bean va a ser pasivado


Ciclo de vida de un bean stateful

Singleton

Explicar beanes singleton, aunque sean de EJB 3.1

....TO DO...

Message Driven Bean (MDB)

Beans que se instancian y activan al recibir mensajes JMS. JMS = Java Messaging System Permiten ejecutar logicas asincronamente.

Message Driven Bean (MDB)


El cliente crea un mensaje. El cliente envia el mensaje a un destino del servidor JMS.

El destino es un buzon donde se reciben y almacenan los mensajes.

El servidor JMS determina quienes tienen que recibir ese mensaje y lo reenvia. El contenedor de EJB instancia los MDB que tengan que procesar el mensaje. Se invoca el metodo onMessage(...) del MDB

Creacion de un (MDB)

POJO anotado con @MessageDriven(mappedName=nombre destino) Implementa el interfaz javax.jms.MessageListener El metodo public void onMessage(Message message) se invocara cuando se reciba un mensaje en el destino indicado

Creacion de un (MDB)

File -> New -> Message Driven Bean (EJB 3.X)

Creacion de un (MDB)

Creacion de un (MDB)
@MessageDriven( mappedName = "pasarelaSMS") public class PasarelaSMS implements MessageListener { public void onMessage(Message message) { MapMessage mensaje = (MapMessage) message; try { int telefono = mensaje.getInt("telefono"); String texto = mensaje.getString("texto"); System.out.println("Telefono: " + telefono + " - Texto: " + texto); } catch (JMSException e) { System.out.println("Error leyendo mensaje: " + e); }

Creacion de un (MDB)

@MessageDriven

Anotacion para los MDB El atributo mappedName indica el destino que escucha el MDB Metodo que recibe los mensajes dirigidos al destino escuchado

public void onMessage(Message message)

Creacion de un (MDB)

Message es un interfaz que implementan las clases/interfaces que transportan los mensajes:

TextMessage

Contiene un String Transporta un objeto serializable Mapa con claves y valores

ObjectMessage

MapMessage

ByteMessage StreamMessage

Envio de un mensaje
@Stateless public class Notificaciones implements NotificacionesRemote { @Resource(name = "jms/ConnectionFactory") private ConnectionFactory connectionFactory; @Resource(name = "jms/QueueSMS") private Destination queueSMS; public void envioSMS(int telefono, String texto) { try { Connection connection = connectionFactory.createConnection(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(queueSMS); MapMessage message = session.createMapMessage(); message.setInt("telefono", telefono); message.setString("texto", texto); messageProducer.send(message); } catch (Exception e) { ... }

Configuracion del destino JMS

Common Tasks ->Resources -> JMS Resources

Configuracion del destino JMS

Connection Factories -> New


Pool Name: jms/ConnectionFactory Resource Type: javax.jms.ConnectionFactory

Configuracion del destino JMS

Destination Resources -> New


JNDI Name: jms/QueueSMS Physical Destination Name: jmsQueueSMS Resource Type: javax.jms.Queue

Destinos JMS

Tipos de destino:

javax.jms.Queue:

El mensaje se envia a uno (y solo uno) de los MDB que esten a la escucha del destino. Si el MDB no atiende el mensaje, se guarda hasta que sea atendido El mensaje se envia a todos los MDB que esten a la escucha del destino. Si el MDB no atiende el mensaje, se pierde el mensaje.

javax.jms.Topic:

EJB TIMERS

EJB Timers

El contenedor EJB incluye un scheduler para temporizar la ejecucion de procesos implementados como metodos de los EJB. Los temporizadores generalmente son persistentes!

Podemos apagar el servidor y cuando se reinicie, los procesos temporizados seguiran programados. Algunos contenedores no soporta la persistencia o esta desactivada por defecto.

EJB Timers

Dos tipos de temporizadores:

Simple (Single Action Timer):

Solo se ejecutan una vez y despues expiran Se ejecuta varias veces, cada cierto tiempo.

De Intervalo (Interval Timer

TimerService

Interfaz que permite la creacion de temporizadores:

Simple:

Especificando dentro de cuanto se lanza el timer:

Timer createTimer(long duration, Serializable info) Timer createTimer(Date expiration, Serializable info)

Especificando en que fecha/hora se lanza el timer:

Intervalo:

Timer createTimer(long initialDuration, long intervalDuration, Serializable info) Timer createTimer(Date initialExpiration, long intervalDuration, Serializable info)

TimerService

Tambien permite recuperar todos los timers para recorrerlos:

Collection getTimers() @Resource TimerService timerService;

Se recupera mediante inyeccion

Timer

Interfaz que permite acceder al temporizador

Serializable getInfo ():

Devuelve la informacion que se asocio al timer al crearlo Fecha del proximo timeout Milisegundos hasta el proximo timeout Cancela el temporizador

Date getNextTimeout():

long getTimeRemaining():

void cancel():

TimedObject

EJB que se invocara al expirar el temporizador Se anota con @Timeout el metodo a ejecutar:
@Timeout public void myTimedOutMethod(Timer timer){ ... }

Alternativamente (EJB 2.1 o superior), se puede implementar el metodo void ejbTimedout(Timer timer) del interfaz javax.ejb.TimedObject

PruebaTimer.java
@Stateless public class PruebaTimer implements PruebaTimerRemote{ static final String nombreTimer = "temporizador Prueba"; @Resource TimerService timerService; @Timeout public void execute(Timer timer) { System.out.println("Timer: " + timer.getInfo()); } public void inicializarTimer() { cancelarTimer(); timerService.createTimer(5000,1000, nombreTimer); } ...

PruebaTimer.java
... public void cancelarTimer() { Collection<Timer> timers = timerService.getTimers(); if (timers != null) { for (Timer t : timers) { t.cancel(); System.out.println("Cancelando timer " + t); } }

} }

Schedule

La anotacion @schedule permite programar la ejecucion de un metodo a un dia y hora determinada Se puede utilizar varias veces en un mismo EJB para programar varios metodos EXISTE DESDE LA VERSION 3.1!!!!

Schedule

La anotacion toma como atributos la fecha de ejecucion del metodo:


Second Minute Hour DayOfWeek DayOfMonth Month Year

Los atributos aceptan asteriscos y rangos

JPA & EJB

Creando un datasource

http://www.albeesonline.com/blog/2008/08/06/creatingConfigurar: DatabaseName / Password / URL/ url / ServerName / User

Configurando el persistence.xml

Tipo de transaccion: JTA (eclipselink nos obliga a usar datasource) Explicar diferencia entre JTA y local_resource

Inyeccion de un persistenceContext (em)


Persistence Context == Cache Entity Manager -> accede al contexto. Se inyecta siempre el mismo persistenceContext, lo que puede ser problemtico en entornos multitarea

Inyeccion del PersistenceUnit (emf)

Interceptor

Interceptando metodos:

@AroundInvoke public Object logger(InvocationContext invocationContext) throws Exception { ... return invocationContext.proceed(); }

public class Registro { @AroundInvoke public Object logger(InvocationContext invocationContext) throws Exception { System.out.println("Interceptado: " + invocationContext.getTarget().getClass() + " - " + invocationContext.getMethod() + " - " + invocationContext.getParameters()); return invocationContext.proceed();

}
@PostConstruct public Object postConstruct(InvocationContext invocationContext) throws Exception { System.out.println("Creado: " + invocationContext.getTarget().getClass()); return invocationContext.proceed();

} }

@ExcludeClassInterceptors @ExcludeDefaultInterceptors