====== Novedades EJB 3.1 ======
La actualización a EJB 3.1 conlleva un conjunto de mejoras importantes que facilitan el manejo, acceso y gestión de los EJB.
====Acceso sin interfaz====
En EJB 3.1 no es necesario que un EJB implemente un determinado interfaz para proveer acceso local a sus métodos. El cliente podrá acceder a cualquier método **público** de un EJB una vez lo recupere. El siguiente ejemplo ilustra esto:
@Stateless
public class PruebaEJB {
public String holaMundo() {
return "Hola Mundo";
}
}
public class HolaMundoClass{
@EJB
private PruebaEJB pruebaEJB ;
public String diHola() {
return pruebaEJB.holaMundo();
}
}
Como podemos ver el EJB no implementa ninguna interfaz y en cambio la clase HolaMundoClass puede acceder sin problemas a sus métodos públicos. No obstante existen ciertas limitaciones sobre esta nueva funcionalidad:
* El cliente nunca puede usar al operador new para adquierir la referencia, debe obtener el EJB por una referencia existente.
* Si se intenta invocar un método que no es público se producirá una EJBException.
* Si se expone una interfaz local, sólo serán accesibles los métodos de esa interfaz aunque tenga otros públicos.
====Anotaciones====
En esta nueva versión tenemos un conjunto nuevo de anotaciones que nos mejoran y amplían las posibilidades existentes a la hora de diseñar nuestra aplicación.
**@Asynchronous **: Permite marcar un método como asíncrono. El método devolverá un objeto de tipo **Future** que inicialmente estará vacío y se rellenará cuando la ejecución del método se complete.
Los métodos asíncronos sólo pueden devolver tipo de objeto **Future** o ser **void**.
@Singleton
public class B {
...
@Asynchronous
public void flushBye() { ... }
...
@Asynchronous
public Future sayBye() {
...
return new AsyncResult(bye);
}
}
La interfaz Future provee los siguientes métodos:
* **cancel (boolean mayInterruptIfRunning)**: Intenta cancelar la ejecución del método asíncrono. El contenedor intentará cancelar la invocación si todavía no fue iniciada. Si la cancelación resulta exitosa el método devuelve true, sino false. El parámetro mayInterruptIfRunning controla, en caso de que no pueda detenerse la invocación, si el bean destino tiene visibilidad del pedido de cancelación por parte del cliente.
* **get**: Devuelve el resultado del método cuando termina. Este método tiene dos versiones sobrecargadas, una que se bloquea hasta que termine la ejecución, y la otra que recibe un timeout como parámetro.
* **isCancelled**: Indica si el método fue cancelado.
* **isDone**: Indica si el método terminó exitosamente.
**@Singleton**: Nos permite crear de manera automática el singleton de una bean determinado creando lo que se conoce como Singleton Session Bean. El comportamiento en este caso, es el de un bean que se crea una única vez por aplicación y que puede ser instanciado por cualquier cliente, permitiéndose un acceso concurrente al mismo. [[http://www.davidmarco.es/articulo/introduccion-a-ejb-3-1-iii|Referencias y Ejemplos]]
@Singleton
public class A { (...) }
====Timer Service====
Este servidio incluido en la nueva versión de EJB nos permite realizar tareas guiadas por instantes de tiempo. Ahorrando así el uso de otras tecnologías que antes eran necesarias para esta tarea como Quartz o Flux.
La anotación **@Schedule** se utiliza para crear un timer de forma automática, que coge como parámetro el timeout correspondiente a la ejecución. Esta anotación se aplica al método que será utilizado como callback del timeout. En el siguiente ejemplo se definen dos timers, uno que expira cada lunes a la medianoche y el otro que expira el último día de cada mes.
@Stateless
public class TimerEJB {
@Schedule(dayOfWeek="Mon")
public void itIsMonday(Timer timer) { (...) }
@Schedule(dayOfMonth="Last")
public void itIsEndOfMonth(Timer timer) { (...) }
}
Un método puede estar anotado con más de un timer, en el siguiente egemlo definiremos dos timers para el método mealTime, uno de los cuales expira todos los días a la 1pm y el otro expira a las 8pm.
@Stateless
public class MealEJB {
@Schedules(
{ @Schedule(hour="13"),
@Schedule(hour="20")
}
public void mealTime(Timer timer) { (...) }
}
Los timersser persistentes (por defecto) o no-persistentes. Los timers no-persistentes no sobreviven a un apagado de la aplicación o una caída del contenedor. La persistencia puede definirse usando el atributo persistente de la anotación, o pasando la clase TimerConfig como parámetro del método createTimer en la interfaz TimerService.
Algunos ejemplos más completos de cómo definir un timer:
Todos los martes a las 7.30am
@Schedule(hour = "7", minute = "30", dayOfWeek = "Tue")
De lunes a viernes, a las 7, 15 y 20 horas
@Schedule(hour = "7, 15, 20", dayOfWeek = "Mon-Fri")
Cada hora de los domingos
@Schedule(hour = "*", dayOfWeek = "0")
Último viernes de diciembre, a las 12
@Schedule(hour = "12", dayOfMonth = "Last Fri", month="Dec")
Tres días antes del fin de mes, para cada mes del 2009, a las 8pm
@Schedule(hour = "20", dayOfMonth = "-3", year="2009")
Cada 5 minutos de todas las horas, comenzando a las 3pm
@Schedule(minute = "*/5", hour = "15/1")
===== Referencias =====
[[http://www.dosideas.com/noticias/java/528-ejb-31-un-paso-importante-hacia-la-madurez.html|EJB 3.1: un paso importante hacia la madurez]]
[[http://www.davidmarco.es/articulo/introduccion-a-ejb-3-1-i|Introduccion a EJB 3.1 (I)]] - [[http://www.davidmarco.es/articulo/introduccion-a-ejb-3-1-ii|(II)]] - [[http://www.davidmarco.es/articulo/introduccion-a-ejb-3-1-iii|(III)]] - [[http://www.davidmarco.es/articulo/introduccion-a-ejb-3-1-iv|(IV)]]
[[http://www.arquitecturajava.com/java-ee-6-portable-jndi/|JEE6 Portable JNDI]]
[[http://www.arquitecturajava.com/ejb-name-beanname-y-mappedname/|EJB name, beanName y mappedName]]