Tareas programadas con Spring Framework y JDK Timer

Tareas programadas con Spring Framework y JDK Timer

Seguro que en más de una ocasión, durante el desarrollo de una aplicación has necesitado ejecutar una tarea de forma periódica. Para desarrollar esto, desde la versión 1.3 del JDK se incluye las clases java.util.Timer y java.util.TimerTask. Estas clase facilitan la programación de tareas para ejecuciones futuras en un thread en segundo plano. Las tareas pueden ser programadas para ejecutarse una vez o múltiples veces a intervalos regulares.

En el caso de que necesites una planificación más compleja, la clase Timer se quedará corta en varios aspectos y deberás utilizar un planificador como Quartz o similar. En este hilo de StackOverflow puedes ver otras alternativas. En este artículo vamos a utilizar las clases wrapper de Spring, que internamente hacen uso de las del JDK, para ejecutar una tarea a intervalos regulares de tiempo dentro de una aplicación web J2EE con el framework de Spring.

Lo primero que vamos a crear es la tarea a ejecutar. Será un método público dentro de una clase pública, tal y como se muestra en el siguiente código:

package es.activity.schedule;

public class RunMeTask
{
	public void printMe() {
		System.out.println("Ejecutando tarea programada");
	}
}

A continuación abrimos para editar el fichero XML de contexto de nuestra aplicación web Spring y añadimos un bean que haga referencia a la clase anterior:

<bean id="runMeTask" class="es.activity.schedule.RunMeTask" />

Vamos a definir a continuación, en el mismo fichero, el método de la clase que ejecutará el código de la tarea. Spring incorpora la clase MethodInvokingTimerTaskFactoryBean para reemplazar la clase TimerTask del JDK.

<bean id="schedulerTask" 
  class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
	<property name="targetObject" ref="runMeTask" />
	<property name="targetMethod" value="printMe" />
</bean>

Ahora vamos a definir cada cuánto se ejecutará utilizando la clase ScheduledTimerTask, que reemplaza a la clase Timer del JDK. Le pasamos como propiedades al bean tanto el retardo (delay) para la primera ejecución, como el intervalo (period) para sucesivas ejecuciones. Ambos valores en milisegundos. En el ejemplo se ejecutará un segundo después del despliegue de la aplicación y a continuación cada 60 segundos.

<bean id="timerTask"
	class="org.springframework.scheduling.timer.ScheduledTimerTask">
	<property name="timerTask" ref="schedulerTask" />
	<property name="delay" value="1000" />
	<property name="period" value="60000" />
</bean>

Hasta ahora se trata de configurar de manera declarativa lo referente a la tarea. Vamos a ejecutar el timer para que comience la ejecución:

<bean class="org.springframework.scheduling.timer.TimerFactoryBean">
	<property name="scheduledTimerTasks">
		<list>
			<ref local="timerTask" />
		</list>
	</property>
</bean>

Cómo ves no es necesario introducir ninguna llamada por código a la tarea programada. La clase TimerFactoryBean se encarga de ejecutar el código del método PrintMe() durante el despliegue de la aplicación en el servidor, con un retardo de 1 segundo la primera vez y luego cada 60 segundos.

Actualización (24/01/2013). Para completar la información quizás te interese cómo integrar Spring con el planificador Quartz. Por ello publiqué otro artículo posteriormente con el título «Tareas programadas con Spring y Quartz».


2 respuestas a “Tareas programadas con Spring Framework y JDK Timer”

  1. Buenísimo el artículo.

    Estaba buscando como hacer algo similar con quartz y da la casualidad que mi proyecto es spring. Me estaba volviendo un poco loco para echar a andar quartz con mi proyecto y siguiendo tus indicaciones solo he tenido que editar el applicationContext y soltar la clase que quiero que haga el automatismo y ha funcionado a la primera.

    Gracias!!

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para su aceptación y la de nuestra política de cookies.

ACEPTAR
Aviso de cookies