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<String> sayBye() {
    ...
    return new AsyncResult<String>(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. 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")
  • fdw2.0/fundeweb2.0/gt/novedades_ejb31.txt
  • Última modificación: 07/11/2017 10:46
  • (editor externo)