La anotación @Scheduled en Spring

1. Información general

En este tutorial, ilustraremos cómo se puede usar la anotación Spring @Scheduled para configurar y programar tareas.

Las reglas simples que debemos seguir para anotar un método con @Scheduled son:

  • un método debe tener el tipo de retorno vacío
  • un método no debe aceptar ningún parámetro

2. Habilite la compatibilidad con la programación

Para habilitar el soporte para tareas de programación y la anotación @Scheduled en Spring, podemos usar la anotación de estilo de habilitación de Java:

@Configuration @EnableScheduling public class SpringConfig { ... }

Por el contrario, podemos hacer lo mismo en XML:

3. Programe una tarea con retraso fijo

Comencemos configurando una tarea para que se ejecute después de un retraso fijo:

@Scheduled(fixedDelay = 1000) public void scheduleFixedDelayTask() { System.out.println( "Fixed delay task - " + System.currentTimeMillis() / 1000); }

En este caso, la duración entre el final de la última ejecución y el inicio de la siguiente ejecución es fija. La tarea siempre espera hasta que finalice la anterior.

Esta opción debe usarse cuando sea obligatorio que la ejecución anterior se complete antes de volver a ejecutarse.

4. Programe una tarea a un ritmo fijo

Ejecutemos ahora una tarea en un intervalo de tiempo fijo:

@Scheduled(fixedRate = 1000) public void scheduleFixedRateTask() { System.out.println( "Fixed rate task - " + System.currentTimeMillis() / 1000); }

Esta opción debe usarse cuando cada ejecución de la tarea sea independiente.

Tenga en cuenta que las tareas programadas no se ejecutan en paralelo de forma predeterminada. Entonces, incluso si usamos FixedRate , la siguiente tarea no se invocará hasta que se complete la anterior.

Si queremos admitir el comportamiento paralelo en las tareas programadas, debemos agregar la anotación @Async :

@EnableAsync public class ScheduledFixedRateExample { @Async @Scheduled(fixedRate = 1000) public void scheduleFixedRateTaskAsync() throws InterruptedException { System.out.println( "Fixed rate task async - " + System.currentTimeMillis() / 1000); Thread.sleep(2000); } }

Ahora, esta tarea asincrónica se invocará cada segundo, incluso si la tarea anterior no se ha realizado.

5. Tasa fija frente a demora fija

Podemos ejecutar una tarea programada usando la anotación @Scheduled de Spring , pero según las propiedades fixedDelay y fixedRate, la naturaleza de la ejecución cambia.

La propiedad fixedDelay asegura que haya un retraso de n milisegundos entre el tiempo de finalización de una ejecución de una tarea y el tiempo de inicio de la siguiente ejecución de la tarea.

Esta propiedad es especialmente útil cuando necesitamos asegurarnos de que solo se ejecute una instancia de la tarea todo el tiempo. Para trabajos dependientes, es muy útil.

La propiedad fixedRate ejecuta la tarea programada cada n milisegundos. No comprueba si hay ejecuciones anteriores de la tarea.

Esto es útil cuando todas las ejecuciones de la tarea son independientes. Si no esperamos exceder el tamaño de la memoria y el grupo de subprocesos, fixedRate debería ser bastante útil.

Aunque, si las tareas entrantes no terminan rápidamente, es posible que terminen con la "excepción de memoria insuficiente".

6. Programe una tarea con retraso inicial

A continuación, programemos una tarea con un retraso (en milisegundos):

@Scheduled(fixedDelay = 1000, initialDelay = 1000) public void scheduleFixedRateWithInitialDelayTask() { long now = System.currentTimeMillis() / 1000; System.out.println( "Fixed rate task with one second initial delay - " + now); }

Observe cómo estamos usando tanto FixedDelay como initialDelay en este ejemplo. La tarea se ejecutará la primera vez después del valor initialDelay y continuará ejecutándose de acuerdo con fixedDelay .

Esta opción es conveniente cuando la tarea tiene una configuración que debe completarse.

7. Programe una tarea usando expresiones cron

A veces, los retrasos y las tasas no son suficientes, y necesitamos la flexibilidad de una expresión cron para controlar la programación de nuestras tareas:

@Scheduled(cron = "0 15 10 15 * ?") public void scheduleTaskUsingCronExpression() { long now = System.currentTimeMillis() / 1000; System.out.println( "schedule tasks using cron jobs - " + now); }

Tenga en cuenta que en este ejemplo, estamos programando una tarea para que se ejecute a las 10:15 a.m. del día 15 de cada mes.

De forma predeterminada, Spring utilizará la zona horaria local del servidor para la expresión cron. Sin embargo, podemos usar el atributo de zona para cambiar esta zona horaria :

@Scheduled(cron = "0 15 10 15 * ?", zone = "Europe/Paris")

Con esta configuración, Spring programará el método anotado para que se ejecute a las 10:15 a. M. El día 15 de cada mes en la hora de París.

8. Parametrización del horario

Codificar estos programas es simple, pero generalmente necesitamos poder controlar el programa sin volver a compilar y volver a implementar la aplicación completa.

Usaremos Spring Expressions para externalizar la configuración de las tareas y las almacenaremos en archivos de propiedades.

Una tarea de retraso fijo :

@Scheduled(fixedDelayString = "${fixedDelay.in.milliseconds}")

Una tarea de FixedRate :

@Scheduled(fixedRateString = "${fixedRate.in.milliseconds}")

Una tarea basada en una expresión cron :

@Scheduled(cron = "${cron.expression}")

9. Configuración de tareas programadas mediante XML

Spring también proporciona una forma XML de configurar las tareas programadas. Aquí está la configuración XML para configurarlos:

10. Conclusión

En este artículo, discutimos la forma de configurar y usar la anotación @Scheduled .

Cubrimos el proceso para habilitar la programación y varias formas de configurar los patrones de tareas de programación.

Los ejemplos que se muestran arriba se pueden encontrar en GitHub.