2009-08-12 26 views
10

Necesito crear un temporizador de intervalo que se configura para ejecutarse una vez a la semana automáticamente. No quiero que comience en función de la entrada del usuario, pero quiero que se cree cuando la aplicación se implementa en el servidor. Cada ejemplo que he visto tiene otra clase que inicia el temporizador. No quiero usar un bean controlado por mensaje para crear el temporizador porque la auditoría solo debe consultar una base de datos durante un período de tiempo dado y no se basa en acciones que envían mensajes.¿Cómo iniciar un EJB Timer en la implementación?

He incluido un ejemplo de un temporizador. En el siguiente ejemplo, el temporizador debe disparar cada 10 minutos. Como prueba, quiero que el temporizador dispare cada 10 minutos para poder probar el temporizador.

@Stateless 
public class TimerTest implements 
     TimerTestLocal, TimerTestRemote{ 

    @Resource 
    private TimerService timerService; 
    private Logger log = Logger.getLogger(TimerTest.class); 
    private long interval = 1000 * 60 * 10; 
    private static String TIMER_NAME = "AuditTimer"; 

    public void scheduleTimer() throws NamingException { 
     // TODO Auto-generated method stub 
     Calendar cal = Calendar.getInstance(); 
     //cal.set(Calendar.HOUR_OF_DAY, 23);//run at 11pm 
     //cal.set(Calendar.MINUTE, 00); 
     //cal.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY); 
     SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy hh:mm"); 
     log.debug("schedule for: " + sdf.format(cal.getTime())); 

     timerService.createTimer(cal.getTime(), interval, TIMER_NAME); 
    } 

    public void cancelTimer() { 
     for(Object obj : timerService.getTimers()) 
     { 
      Timer timer = (Timer)obj; 
      if(timer.getInfo().equals(TIMER_NAME)) 
       timer.cancel(); 
     } 
    } 

    @Timeout 
    public void timerEvent(Timer timer) { 
     log.debug("timer fired"); 
    } 


} 

Entonces, ¿hay alguna forma de que pueda iniciar este temporizador cuando se implementa la aplicación? No creo que sea una buena idea colocar la creación del temporizador en un método @PostConstruct porque los cargadores de clase están en el servidor.

Respuesta

16

La forma en que he hecho los temporizadores en el pasado es crear un oyente de contexto en el web.xml para configurar el temporizador.

De esta forma puede asegurarse de que se inicie con el contenedor y apagarse limpiamente cuando se quite la aplicación.

+0

Eso funcionó muy bien. Gracias. – scheibk

1

No sé si puede funcionar el uso del contextListener para iniciar el temporizador. De este artículo, how to use EJb 3 timer in a weblogic 10 cluster, parece que puede encontrarse con algunos problemas en weblogic 10.3.2.

+0

Encontré el mismo problema en JBoss EAP 5.1. El EJB no está accesible en el momento en que se invoca el detector de contexto. – mekondelta

24

Si su proyecto puede usar jee6/ejb3.1 hay una solución mucho mejor a este problema. http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html

@javax.ejb.Schedule(minute="*/10", hour="*") 
public void automaticTimeout() { 
    logger.info("Automatic timeout occured"); 
} 

Mediante el uso de la nueva anotación @Schedule que tienen un amplio control sobre cuándo y con qué frecuencia se llama un método de tiempo de espera. La gran ventaja: ya no es necesario iniciar el temporizador "desde afuera".

Oracle escribe:

temporizadores automáticos son creados por el contenedor EJB cuando un enterprise bean que contiene métodos anotados con el @Schedule o @Schedules anotaciones se despliega. Un enterprise bean puede tener múltiples métodos de tiempo de espera automático , a diferencia de un temporizador programático, que permite solo un método anotado con la anotación @Timeout en la clase enterprise bean .

+0

Para responder a su otra pregunta – seafoxx